106 lines
2.2 KiB
Svelte
106 lines
2.2 KiB
Svelte
<script lang="ts">
|
|
import { onDestroy, type Snippet } from 'svelte';
|
|
import { get } from 'svelte/store';
|
|
import { serialState, setSerialContext } from './serial.store';
|
|
import * as service from './serial.service';
|
|
import { getDeviceName } from '$lib/utils/device';
|
|
|
|
interface Props {
|
|
children?: Snippet;
|
|
}
|
|
|
|
let { children }: Props = $props();
|
|
|
|
async function requestPort() {
|
|
serialState.update((state) => ({
|
|
...state,
|
|
status: 'requesting',
|
|
error: undefined,
|
|
}));
|
|
|
|
try {
|
|
const port = await service.requestPort();
|
|
if (!port) return null;
|
|
|
|
const info = port.getInfo?.();
|
|
const name = info
|
|
? (getDeviceName(info) ??
|
|
`USB ${info.usbVendorId ?? ''}:${info.usbProductId ?? ''}`)
|
|
: 'Serial Device';
|
|
serialState.update((s) => ({
|
|
...s,
|
|
port,
|
|
portName: name,
|
|
status: 'idle',
|
|
}));
|
|
|
|
return port;
|
|
} catch (err) {
|
|
serialState.update((s) => ({
|
|
...s,
|
|
status: 'error',
|
|
error: String(err),
|
|
}));
|
|
return null;
|
|
}
|
|
}
|
|
|
|
async function openPort(options: SerialOptions) {
|
|
let port = get(serialState).port;
|
|
if (!port) return;
|
|
|
|
serialState.update((s) => ({
|
|
...s,
|
|
status: 'connecting',
|
|
error: undefined,
|
|
}));
|
|
|
|
try {
|
|
await service.openPort(port, options);
|
|
serialState.update((s) => ({ ...s, status: 'connected' }));
|
|
} catch (err) {
|
|
serialState.update((s) => ({
|
|
...s,
|
|
status: 'error',
|
|
error: String(err),
|
|
}));
|
|
}
|
|
}
|
|
|
|
async function closePort() {
|
|
let port = get(serialState).port;
|
|
|
|
if (!port) return;
|
|
|
|
serialState.update((s) => ({ ...s, status: 'disconnecting' }));
|
|
await service.closePort(port);
|
|
|
|
serialState.update((s) => ({
|
|
...s,
|
|
status: 'idle',
|
|
}));
|
|
}
|
|
|
|
async function reopenPort(options: SerialOptions) {
|
|
await closePort();
|
|
await openPort(options);
|
|
}
|
|
|
|
setSerialContext({
|
|
state: {
|
|
subscribe: serialState.subscribe,
|
|
},
|
|
requestPort,
|
|
openPort,
|
|
reopenPort,
|
|
closePort,
|
|
});
|
|
|
|
onDestroy(() => {
|
|
let port = get(serialState).port;
|
|
if (port) service.closePort(port);
|
|
});
|
|
</script>
|
|
|
|
{@render children?.()}
|