Skip to content

Instantly share code, notes, and snippets.

@KSXGitHub
Created August 4, 2019 06:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KSXGitHub/a6aac89f709173c9a3a8eda9403bc899 to your computer and use it in GitHub Desktop.
Save KSXGitHub/a6aac89f709173c9a3a8eda9403bc899 to your computer and use it in GitHub Desktop.
import xs from 'xstream'
import spawn from 'advanced-spawn-async'
import { Option, Some, some, none, match } from '@tsfun/option'
export enum Status {
Plugged = 'Plugged',
Unplugged = 'Unplugged'
}
type UnknownStatus = Status | 'Unknown'
export function checkStatus (): Promise<UnknownStatus> {
return spawn('acpi', ['-a']).onclose.then(
x => analyzeAcpiOutput(x.stdout.trim())
? Status.Plugged
: Status.Unplugged,
(): 'Unknown' => 'Unknown'
)
}
export function analyzeAcpiOutput (output: string) {
return /on-line/i.test(output)
}
export const statusStream = xs.periodic(1000)
.map(() => xs.fromPromise(checkStatus()))
.flatten()
.filter((status): status is Status => status !== 'Unknown')
export class StatusPair {
constructor (
public readonly oldStatus: Status,
public readonly newStatus: Status
) {}
}
export const statusPairStream = statusStream.fold(
(pair: Option<StatusPair>, status: Status): Option<StatusPair> => {
return some(new StatusPair(
pair.tag ? pair.value.newStatus : status,
status
))
},
none()
)
export enum Event {
Init = 'Init',
Plugged = 'Plugged',
Unplugged = 'Unplugged'
}
export const eventStream = statusPairStream
.map((maybePair): Option<Event> => match(maybePair, {
none: () => some(Event.Init),
some ({ oldStatus, newStatus }): Option<Event> {
if (oldStatus === newStatus) return none()
switch (newStatus) {
case Status.Plugged:
return some(Event.Plugged)
case Status.Unplugged:
return some(Event.Unplugged)
}
}
}))
.filter((option): option is Some<Event> => option.tag)
.map(x => x.value)
export const initEventStream = eventStream
.filter((event): event is Event.Init => event === Event.Init)
export const pluggedEventStream = eventStream
.filter((event): event is Event.Plugged => event === Event.Plugged)
export const unpluggedEventStream = eventStream
.filter((event): event is Event.Unplugged => event === Event.Unplugged)
// ---------
initEventStream.addListener({
next: event => console.info('init', event)
})
pluggedEventStream.addListener({
next: event => console.info('plugged', event)
})
unpluggedEventStream.addListener({
next: event => console.info('unplugged', event)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment