feat: 实现SerialProvider

- SerialProvider用于为串口连接提供context
This commit is contained in:
2025-12-24 15:01:38 +08:00
parent 00bd397986
commit b841b2641c
6 changed files with 255 additions and 1 deletions

View File

@ -0,0 +1,103 @@
<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';
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
? `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?.()}