feat: 实现SerialProvider
- SerialProvider用于为串口连接提供context
This commit is contained in:
103
src/lib/serial/serial.providers.svelte
Normal file
103
src/lib/serial/serial.providers.svelte
Normal 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?.()}
|
||||
Reference in New Issue
Block a user