ngx-web-serial 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +65 -0
- package/esm2022/lib/mock-serial.mjs +31 -0
- package/esm2022/lib/ngx-web-serial.service.mjs +124 -0
- package/esm2022/ngx-web-serial.mjs +5 -0
- package/esm2022/public-api.mjs +5 -0
- package/fesm2022/ngx-web-serial.mjs +165 -0
- package/fesm2022/ngx-web-serial.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/mock-serial.d.ts +8 -0
- package/lib/ngx-web-serial.service.d.ts +30 -0
- package/package.json +25 -0
- package/public-api.d.ts +1 -0
package/README.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
[![npm version](https://badge.fury.io/js/angular-web-serial.svg?icon=si%3Anpm)](https://badge.fury.io/js/angular-web-serial)
|
2
|
+
[![Publish to GitHub Packages](https://github.com/mattfors/ngx-web-serial/actions/workflows/build.yml/badge.svg)](https://github.com/mattfors/ngx-web-serial/actions/workflows/build.yml)
|
3
|
+
[![codecov](https://codecov.io/github/mattfors/ngx-web-serial/graph/badge.svg?token=GRL2B8OCW5)](https://codecov.io/github/mattfors/ngx-web-serial)
|
4
|
+
|
5
|
+
# Angular Web Serial
|
6
|
+
|
7
|
+
Angular Web Serial is an angular module for connecting to serial devices with the Web Serial API.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
```shell
|
12
|
+
npm i angular-web-serial
|
13
|
+
```
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
Below is the basic usage of the module. A pipe is used to accumulate the raw data from the serial port.
|
17
|
+
```typescript
|
18
|
+
import { Component } from '@angular/core';
|
19
|
+
import { AngularSerialService, provideAngularSerial } from '../../../ngx-web-serial/src';
|
20
|
+
import { Observable, scan } from 'rxjs';
|
21
|
+
import { AsyncPipe } from '@angular/common';
|
22
|
+
|
23
|
+
@Component({
|
24
|
+
selector: 'app-root',
|
25
|
+
standalone: true,
|
26
|
+
imports: [AsyncPipe],
|
27
|
+
providers: [provideAngularSerial()],
|
28
|
+
template: `
|
29
|
+
<button (click)="open()">Open</button>
|
30
|
+
<input #inputField
|
31
|
+
type="text"
|
32
|
+
(keydown.enter)="write(inputField.value); inputField.value=''"
|
33
|
+
placeholder="Type and press Enter">
|
34
|
+
<div>
|
35
|
+
<textarea [value]="data$ | async" readonly></textarea>
|
36
|
+
</div>
|
37
|
+
`
|
38
|
+
})
|
39
|
+
export class AppComponent {
|
40
|
+
|
41
|
+
data$: Observable<string>;
|
42
|
+
|
43
|
+
constructor(private serial: AngularSerialService) {
|
44
|
+
this.data$ = this.serial.read().pipe(
|
45
|
+
scan((acc, value) => acc + value, '')
|
46
|
+
);
|
47
|
+
}
|
48
|
+
|
49
|
+
open(): void {
|
50
|
+
this.serial.open().subscribe()
|
51
|
+
}
|
52
|
+
|
53
|
+
write(value: string): void {
|
54
|
+
this.serial.write(value + '\r').subscribe();
|
55
|
+
}
|
56
|
+
|
57
|
+
}
|
58
|
+
|
59
|
+
```
|
60
|
+
|
61
|
+
## Mock serial device
|
62
|
+
The module can be used with a mock serial device for testing or if you do not have a real serial device. Provide a function which takes and returns a string. In this example, the text transmitted to the serial device will be echoed back with 'Hello'.
|
63
|
+
```typescript
|
64
|
+
providers: [provideAngularSerialTest(i => `Hello ${i}!\n`)]
|
65
|
+
```
|
@@ -0,0 +1,31 @@
|
|
1
|
+
export class MockSerial {
|
2
|
+
constructor(responseFunction) {
|
3
|
+
this.readableController = null;
|
4
|
+
this.responseFunction = responseFunction;
|
5
|
+
this.readableStream = new ReadableStream({
|
6
|
+
start: (controller) => {
|
7
|
+
this.readableController = controller;
|
8
|
+
},
|
9
|
+
cancel: () => {
|
10
|
+
this.readableController = null;
|
11
|
+
}
|
12
|
+
});
|
13
|
+
}
|
14
|
+
requestPort(options) {
|
15
|
+
return Promise.resolve({
|
16
|
+
open: () => Promise.resolve(),
|
17
|
+
close: () => this.readableStream.cancel(),
|
18
|
+
readable: this.readableStream,
|
19
|
+
writable: new WritableStream({
|
20
|
+
write: (chunk) => {
|
21
|
+
const input = new TextDecoder().decode(chunk);
|
22
|
+
const response = this.responseFunction(input);
|
23
|
+
if (this.readableController) {
|
24
|
+
this.readableController.enqueue(new TextEncoder().encode(response));
|
25
|
+
}
|
26
|
+
}
|
27
|
+
})
|
28
|
+
});
|
29
|
+
}
|
30
|
+
}
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9jay1zZXJpYWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtd2ViLXNlcmlhbC9zcmMvbGliL21vY2stc2VyaWFsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sT0FBTyxVQUFVO0lBSXJCLFlBQVksZ0JBQTJDO1FBSC9DLHVCQUFrQixHQUF1RCxJQUFJLENBQUM7UUFJcEYsSUFBSSxDQUFDLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDO1FBQ3pDLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxjQUFjLENBQUM7WUFDdkMsS0FBSyxFQUFFLENBQUMsVUFBVSxFQUFFLEVBQUU7Z0JBQ3BCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxVQUFVLENBQUM7WUFDdkMsQ0FBQztZQUNELE1BQU0sRUFBRSxHQUFHLEVBQUU7Z0JBQ1gsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQztZQUNqQyxDQUFDO1NBQ0YsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFdBQVcsQ0FBQyxPQUFrQztRQUM1QyxPQUFPLE9BQU8sQ0FBQyxPQUFPLENBQUM7WUFDckIsSUFBSSxFQUFFLEdBQUcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUU7WUFDN0IsS0FBSyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFO1lBQ3pDLFFBQVEsRUFBRSxJQUFJLENBQUMsY0FBYztZQUM3QixRQUFRLEVBQUUsSUFBSSxjQUFjLENBQUM7Z0JBQzNCLEtBQUssRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFO29CQUNmLE1BQU0sS0FBSyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUM5QyxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQzlDLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7d0JBQzVCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsSUFBSSxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztvQkFDdEUsQ0FBQztnQkFDSCxDQUFDO2FBQ0YsQ0FBQztTQUNrQixDQUFDLENBQUM7SUFDMUIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNsYXNzIE1vY2tTZXJpYWwge1xuICBwcml2YXRlIHJlYWRhYmxlQ29udHJvbGxlcjogUmVhZGFibGVTdHJlYW1EZWZhdWx0Q29udHJvbGxlcjxVaW50OEFycmF5PiB8IG51bGwgPSBudWxsO1xuICByZWFkb25seSByZXNwb25zZUZ1bmN0aW9uOiAoaW5wdXQ6IHN0cmluZykgPT4gc3RyaW5nO1xuICByZWFkb25seSByZWFkYWJsZVN0cmVhbTogUmVhZGFibGVTdHJlYW08VWludDhBcnJheT47XG4gIGNvbnN0cnVjdG9yKHJlc3BvbnNlRnVuY3Rpb246IChpbnB1dDogc3RyaW5nKSA9PiBzdHJpbmcpIHtcbiAgICB0aGlzLnJlc3BvbnNlRnVuY3Rpb24gPSByZXNwb25zZUZ1bmN0aW9uO1xuICAgIHRoaXMucmVhZGFibGVTdHJlYW0gPSBuZXcgUmVhZGFibGVTdHJlYW0oe1xuICAgICAgc3RhcnQ6IChjb250cm9sbGVyKSA9PiB7XG4gICAgICAgIHRoaXMucmVhZGFibGVDb250cm9sbGVyID0gY29udHJvbGxlcjtcbiAgICAgIH0sXG4gICAgICBjYW5jZWw6ICgpID0+IHtcbiAgICAgICAgdGhpcy5yZWFkYWJsZUNvbnRyb2xsZXIgPSBudWxsO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcmVxdWVzdFBvcnQob3B0aW9ucz86IFNlcmlhbFBvcnRSZXF1ZXN0T3B0aW9ucyk6IFByb21pc2U8U2VyaWFsUG9ydD4ge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe1xuICAgICAgb3BlbjogKCkgPT4gUHJvbWlzZS5yZXNvbHZlKCksXG4gICAgICBjbG9zZTogKCkgPT4gdGhpcy5yZWFkYWJsZVN0cmVhbS5jYW5jZWwoKSxcbiAgICAgIHJlYWRhYmxlOiB0aGlzLnJlYWRhYmxlU3RyZWFtLFxuICAgICAgd3JpdGFibGU6IG5ldyBXcml0YWJsZVN0cmVhbSh7XG4gICAgICAgIHdyaXRlOiAoY2h1bmspID0+IHtcbiAgICAgICAgICBjb25zdCBpbnB1dCA9IG5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShjaHVuayk7XG4gICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSB0aGlzLnJlc3BvbnNlRnVuY3Rpb24oaW5wdXQpO1xuICAgICAgICAgIGlmICh0aGlzLnJlYWRhYmxlQ29udHJvbGxlcikge1xuICAgICAgICAgICAgdGhpcy5yZWFkYWJsZUNvbnRyb2xsZXIuZW5xdWV1ZShuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUocmVzcG9uc2UpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfSBhcyBhbnkgYXMgU2VyaWFsUG9ydCk7XG4gIH1cbn1cbiJdfQ==
|
@@ -0,0 +1,124 @@
|
|
1
|
+
import { Inject, Injectable } from '@angular/core';
|
2
|
+
import { BehaviorSubject, catchError, filter, firstValueFrom, from, interval, map, Observable, Subject, takeUntil, throwError, timer } from 'rxjs';
|
3
|
+
import { DOCUMENT } from '@angular/common';
|
4
|
+
import { MockSerial } from './mock-serial';
|
5
|
+
import * as i0 from "@angular/core";
|
6
|
+
export class NgxWebSerialService {
|
7
|
+
constructor(serial, ngZone) {
|
8
|
+
this.serial = serial;
|
9
|
+
this.ngZone = ngZone;
|
10
|
+
this.port = null;
|
11
|
+
this.abortController = null;
|
12
|
+
this.dataStream = null;
|
13
|
+
this.dataSubject = new Subject();
|
14
|
+
this.writer = null;
|
15
|
+
this.connectedSubject = new BehaviorSubject(false);
|
16
|
+
this.sink = {
|
17
|
+
write: (chunk) => {
|
18
|
+
this.ngZone.run(() => {
|
19
|
+
this.dataSubject.next(chunk);
|
20
|
+
});
|
21
|
+
}
|
22
|
+
};
|
23
|
+
}
|
24
|
+
/**
|
25
|
+
* Establishes a connection to a serial port using the Web Serial API.
|
26
|
+
*/
|
27
|
+
open(serialOptions = { baudRate: 9600 }, options) {
|
28
|
+
return new Observable((observer) => {
|
29
|
+
if (!this.serial) {
|
30
|
+
observer.error('Web serial not supported.');
|
31
|
+
return;
|
32
|
+
}
|
33
|
+
this.serial.requestPort(options)
|
34
|
+
.then((port) => {
|
35
|
+
this.port = port;
|
36
|
+
return this.port.open(serialOptions);
|
37
|
+
})
|
38
|
+
.then(() => {
|
39
|
+
if (!this.port?.readable || !this.port?.writable) {
|
40
|
+
observer.error('Port is not readable or writable.');
|
41
|
+
return;
|
42
|
+
}
|
43
|
+
this.connectedSubject.next(true);
|
44
|
+
this.abortController = new AbortController();
|
45
|
+
this.dataStream = new WritableStream(this.sink);
|
46
|
+
this.writer = this.port?.writable.getWriter();
|
47
|
+
observer.next();
|
48
|
+
return this.port.readable
|
49
|
+
.pipeThrough(new TextDecoderStream())
|
50
|
+
.pipeTo(this.dataStream, { signal: this.abortController.signal })
|
51
|
+
.catch(() => this.closePort().catch((err) => observer.error(err)));
|
52
|
+
})
|
53
|
+
.catch((err) => observer.error(err))
|
54
|
+
.finally(() => observer.complete());
|
55
|
+
});
|
56
|
+
}
|
57
|
+
isConnected() {
|
58
|
+
return this.connectedSubject.asObservable();
|
59
|
+
}
|
60
|
+
read() {
|
61
|
+
return this.dataSubject.asObservable();
|
62
|
+
}
|
63
|
+
write(data) {
|
64
|
+
if (this.writer) {
|
65
|
+
return from(this.writer.write(new TextEncoder().encode(data)));
|
66
|
+
}
|
67
|
+
return throwError(() => new Error('No writer available.'));
|
68
|
+
}
|
69
|
+
waitForReadableUnlock(period = 50, timeout = 5000) {
|
70
|
+
return firstValueFrom(interval(period).pipe(filter(() => !this.port?.readable?.locked), map(() => undefined), takeUntil(timer(timeout)), catchError(() => throwError(() => new Error('Timeout waiting for readable stream to unlock')))));
|
71
|
+
}
|
72
|
+
closePort() {
|
73
|
+
this.abortController = null;
|
74
|
+
if (this.writer) {
|
75
|
+
this.writer.releaseLock();
|
76
|
+
this.writer = null;
|
77
|
+
}
|
78
|
+
if (this.port) {
|
79
|
+
return this.waitForReadableUnlock()
|
80
|
+
.then(() => this.port.close())
|
81
|
+
.then(() => {
|
82
|
+
this.port = null;
|
83
|
+
this.connectedSubject.next(false);
|
84
|
+
});
|
85
|
+
}
|
86
|
+
else {
|
87
|
+
return Promise.resolve();
|
88
|
+
}
|
89
|
+
}
|
90
|
+
close() {
|
91
|
+
if (this.abortController) {
|
92
|
+
this.abortController.abort();
|
93
|
+
}
|
94
|
+
}
|
95
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgxWebSerialService, deps: [{ token: 'Serial' }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
96
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgxWebSerialService }); }
|
97
|
+
}
|
98
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgxWebSerialService, decorators: [{
|
99
|
+
type: Injectable
|
100
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
101
|
+
type: Inject,
|
102
|
+
args: ['Serial']
|
103
|
+
}] }, { type: i0.NgZone }] });
|
104
|
+
export function provideAngularSerial() {
|
105
|
+
return [
|
106
|
+
NgxWebSerialService,
|
107
|
+
{
|
108
|
+
provide: 'Serial',
|
109
|
+
useFactory: (document) => document.defaultView?.navigator?.serial,
|
110
|
+
deps: [DOCUMENT]
|
111
|
+
}
|
112
|
+
];
|
113
|
+
}
|
114
|
+
export function provideAngularSerialTest(responseFunction) {
|
115
|
+
return [
|
116
|
+
NgxWebSerialService,
|
117
|
+
{
|
118
|
+
provide: 'Serial',
|
119
|
+
useFactory: () => new MockSerial(responseFunction || ((input) => input)),
|
120
|
+
deps: []
|
121
|
+
}
|
122
|
+
];
|
123
|
+
}
|
124
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXdlYi1zZXJpYWwuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC13ZWItc2VyaWFsL3NyYy9saWIvbmd4LXdlYi1zZXJpYWwuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQW1CLE1BQU0sRUFBRSxVQUFVLEVBQW9CLE1BQU0sZUFBZSxDQUFDO0FBQ3RGLE9BQU8sRUFDTCxlQUFlLEVBQ2YsVUFBVSxFQUNWLE1BQU0sRUFDTixjQUFjLEVBQ2QsSUFBSSxFQUNKLFFBQVEsRUFDUixHQUFHLEVBQ0gsVUFBVSxFQUNWLE9BQU8sRUFFUCxTQUFTLEVBQ1QsVUFBVSxFQUNWLEtBQUssRUFDTixNQUFNLE1BQU0sQ0FBQztBQUNkLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDOztBQUczQyxNQUFNLE9BQU8sbUJBQW1CO0lBaUI5QixZQUM2QixNQUEwQixFQUM3QyxNQUFjO1FBREssV0FBTSxHQUFOLE1BQU0sQ0FBb0I7UUFDN0MsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQWpCaEIsU0FBSSxHQUFzQixJQUFJLENBQUM7UUFDL0Isb0JBQWUsR0FBMkIsSUFBSSxDQUFDO1FBQy9DLGVBQVUsR0FBMEIsSUFBSSxDQUFDO1FBQ3pDLGdCQUFXLEdBQW9CLElBQUksT0FBTyxFQUFVLENBQUM7UUFDckQsV0FBTSxHQUFtRCxJQUFJLENBQUM7UUFDOUQscUJBQWdCLEdBQTZCLElBQUksZUFBZSxDQUFVLEtBQUssQ0FBQyxDQUFDO1FBRXhFLFNBQUksR0FBb0I7WUFDdkMsS0FBSyxFQUFFLENBQUMsS0FBVSxFQUFFLEVBQUU7Z0JBQ3BCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRTtvQkFDbkIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsS0FB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QUFLO1FBQ0gsSUFBSSxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUMvQixDQUFDO0lBQ0gsQ0FBQzsrR0F4R1UsbUJBQW1CLGtCQWtCcEIsUUFBUTttSEFsQlAsbUJBQW1COzs0RkFBbkIsbUJBQW1CO2tCQUQvQixVQUFVOzswQkFtQk4sTUFBTTsyQkFBQyxRQUFROztBQXlGcEIsTUFBTSxVQUFVLG9CQUFvQjtJQUNsQyxPQUFPO1FBQ0wsbUJBQW1CO1FBQ25CO1lBQ0UsT0FBTyxFQUFFLFFBQVE7WUFDakIsVUFBVSxFQUFFLENBQUMsUUFBa0IsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRSxTQUFTLEVBQUUsTUFBTTtZQUMzRSxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUM7U0FDakI7S0FDRixDQUFDO0FBQ0osQ0FBQztBQUVELE1BQU0sVUFBVSx3QkFBd0IsQ0FBQyxnQkFBNEM7SUFDbkYsT0FBTztRQUNMLG1CQUFtQjtRQUNuQjtZQUNFLE9BQU8sRUFBRSxRQUFRO1lBQ2pCLFVBQVUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLFVBQVUsQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLENBQUMsS0FBYSxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNoRixJQUFJLEVBQUUsRUFBRTtTQUNVO0tBQ3JCLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRmFjdG9yeVByb3ZpZGVyLCBJbmplY3QsIEluamVjdGFibGUsIE5nWm9uZSwgUHJvdmlkZXIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIEJlaGF2aW9yU3ViamVjdCxcbiAgY2F0Y2hFcnJvcixcbiAgZmlsdGVyLFxuICBmaXJzdFZhbHVlRnJvbSxcbiAgZnJvbSxcbiAgaW50ZXJ2YWwsXG4gIG1hcCxcbiAgT2JzZXJ2YWJsZSxcbiAgU3ViamVjdCxcbiAgU3Vic2NyaWJlcixcbiAgdGFrZVVudGlsLFxuICB0aHJvd0Vycm9yLFxuICB0aW1lclxufSBmcm9tICdyeGpzJztcbmltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IE1vY2tTZXJpYWwgfSBmcm9tICcuL21vY2stc2VyaWFsJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE5neFdlYlNlcmlhbFNlcnZpY2Uge1xuXG4gIHByaXZhdGUgcG9ydDogU2VyaWFsUG9ydCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGFib3J0Q29udHJvbGxlcjogQWJvcnRDb250cm9sbGVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgZGF0YVN0cmVhbTogV3JpdGFibGVTdHJlYW0gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBkYXRhU3ViamVjdDogU3ViamVjdDxzdHJpbmc+ID0gbmV3IFN1YmplY3Q8c3RyaW5nPigpO1xuICBwcml2YXRlIHdyaXRlcjogV3JpdGFibGVTdHJlYW1EZWZhdWx0V3JpdGVyPFVpbnQ4QXJyYXk+IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgY29ubmVjdGVkU3ViamVjdDogQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBzaW5rOiBVbmRlcmx5aW5nU2luayA9ICB7XG4gICAgd3JpdGU6IChjaHVuazogYW55KSA9PiB7XG4gICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICB0aGlzLmRhdGFTdWJqZWN0Lm5leHQoY2h1bmspO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdCgnU2VyaWFsJykgcmVhZG9ubHkgc2VyaWFsOiBTZXJpYWwgfCB1bmRlZmluZWQsXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZVxuICApIHtcbiAgfVxuXG4gIC8qKlxuICAgKiBFc3RhYmxpc2hlcyBhIGNvbm5lY3Rpb24gdG8gYSBzZXJpYWwgcG9ydCB1c2luZyB0aGUgV2ViIFNlcmlhbCBBUEkuXG4gICAqL1xuICBvcGVuKHNlcmlhbE9wdGlvbnM6IFNlcmlhbE9wdGlvbnMgPSB7IGJhdWRSYXRlOiA5NjAwIH0sIG9wdGlvbnM/OiBTZXJpYWxQb3J0UmVxdWVzdE9wdGlvbnMpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IE9ic2VydmFibGU8dm9pZD4oKG9ic2VydmVyOiBTdWJzY3JpYmVyPHZvaWQ+KSA9PiB7XG4gICAgICBpZiAoIXRoaXMuc2VyaWFsKSB7XG4gICAgICAgIG9ic2VydmVyLmVycm9yKCdXZWIgc2VyaWFsIG5vdCBzdXBwb3J0ZWQuJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2VyaWFsLnJlcXVlc3RQb3J0KG9wdGlvbnMpXG4gICAgICAgIC50aGVuKChwb3J0OiBTZXJpYWxQb3J0KSA9PiB7XG4gICAgICAgICAgdGhpcy5wb3J0ID0gcG9ydDtcbiAgICAgICAgICByZXR1cm4gdGhpcy5wb3J0Lm9wZW4oc2VyaWFsT3B0aW9ucyk7XG4gICAgICAgIH0pXG4gICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICBpZiAoIXRoaXMucG9ydD8ucmVhZGFibGUgfHwgIXRoaXMucG9ydD8ud3JpdGFibGUpIHtcbiAgICAgICAgICAgIG9ic2VydmVyLmVycm9yKCdQb3J0IGlzIG5vdCByZWFkYWJsZSBvciB3cml0YWJsZS4nKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5jb25uZWN0ZWRTdWJqZWN0Lm5leHQodHJ1ZSk7XG4gICAgICAgICAgdGhpcy5hYm9ydENvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgICAgICAgdGhpcy5kYXRhU3RyZWFtID0gbmV3IFdyaXRhYmxlU3RyZWFtKHRoaXMuc2luayk7XG4gICAgICAgICAgdGhpcy53cml0ZXIgPSB0aGlzLnBvcnQ/LndyaXRhYmxlLmdldFdyaXRlcigpO1xuICAgICAgICAgIG9ic2VydmVyLm5leHQoKTtcbiAgICAgICAgICByZXR1cm4gdGhpcy5wb3J0LnJlYWRhYmxlXG4gICAgICAgICAgICAucGlwZVRocm91Z2gobmV3IFRleHREZWNvZGVyU3RyZWFtKCkpXG4gICAgICAgICAgICAucGlwZVRvKHRoaXMuZGF0YVN0cmVhbSwge3NpZ25hbDogdGhpcy5hYm9ydENvbnRyb2xsZXIuc2lnbmFsfSlcbiAgICAgICAgICAgIC5jYXRjaCgoKSA9PiB0aGlzLmNsb3NlUG9ydCgpLmNhdGNoKChlcnIpID0+IG9ic2VydmVyLmVycm9yKGVycikpKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKChlcnIpID0+IG9ic2VydmVyLmVycm9yKGVycikpXG4gICAgICAgIC5maW5hbGx5KCgpID0+IG9ic2VydmVyLmNvbXBsZXRlKCkpO1xuICAgIH0pO1xuICB9XG5cbiAgaXNDb25uZWN0ZWQoKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdGVkU3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIHJlYWQoKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy5kYXRhU3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIHdyaXRlKGRhdGE6IHN0cmluZyk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIGlmICh0aGlzLndyaXRlcikge1xuICAgICAgcmV0dXJuIGZyb20odGhpcy53cml0ZXIud3JpdGUobmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGRhdGEpKSk7XG5cbiAgICB9XG4gICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gbmV3IEVycm9yKCdObyB3cml0ZXIgYXZhaWxhYmxlLicpKTtcbiAgfVxuXG5cbiAgcHJpdmF0ZSB3YWl0Rm9yUmVhZGFibGVVbmxvY2socGVyaW9kOiBudW1iZXIgPSA1MCwgdGltZW91dDogbnVtYmVyID0gNTAwMCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiBmaXJzdFZhbHVlRnJvbShpbnRlcnZhbChwZXJpb2QpLnBpcGUoXG4gICAgICBmaWx0ZXIoKCkgPT4gIXRoaXMucG9ydD8ucmVhZGFibGU/LmxvY2tlZCksXG4gICAgICBtYXAoKCkgPT4gdW5kZWZpbmVkKSxcbiAgICAgIHRha2VVbnRpbCh0aW1lcih0aW1lb3V0KSksXG4gICAgICBjYXRjaEVycm9yKCgpID0+IHRocm93RXJyb3IoKCkgPT4gbmV3IEVycm9yKCdUaW1lb3V0IHdhaXRpbmcgZm9yIHJlYWRhYmxlIHN0cmVhbSB0byB1bmxvY2snKSkpXG4gICAgKSk7XG4gIH1cblxuICBwcml2YXRlIGNsb3NlUG9ydCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLmFib3J0Q29udHJvbGxlciA9IG51bGw7XG4gICAgaWYgKHRoaXMud3JpdGVyKSB7XG4gICAgICB0aGlzLndyaXRlci5yZWxlYXNlTG9jaygpO1xuICAgICAgdGhpcy53cml0ZXIgPSBudWxsO1xuICAgIH1cbiAgICBpZiAodGhpcy5wb3J0KSB7XG4gICAgICByZXR1cm4gdGhpcy53YWl0Rm9yUmVhZGFibGVVbmxvY2soKVxuICAgICAgICAudGhlbigoKSA9PiB0aGlzLnBvcnQhLmNsb3NlKCkpXG4gICAgICAgIC50aGVuKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnBvcnQgPSBudWxsO1xuICAgICAgICAgIHRoaXMuY29ubmVjdGVkU3ViamVjdC5uZXh0KGZhbHNlKTtcbiAgICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICB9XG4gIH1cbiAgY2xvc2UoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYWJvcnRDb250cm9sbGVyKSB7XG4gICAgICB0aGlzLmFib3J0Q29udHJvbGxlci5hYm9ydCgpO1xuICAgIH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcHJvdmlkZUFuZ3VsYXJTZXJpYWwoKTogUHJvdmlkZXJbXSB7XG4gIHJldHVybiBbXG4gICAgTmd4V2ViU2VyaWFsU2VydmljZSxcbiAgICB7XG4gICAgICBwcm92aWRlOiAnU2VyaWFsJyxcbiAgICAgIHVzZUZhY3Rvcnk6IChkb2N1bWVudDogRG9jdW1lbnQpID0+IGRvY3VtZW50LmRlZmF1bHRWaWV3Py5uYXZpZ2F0b3I/LnNlcmlhbCxcbiAgICAgIGRlcHM6IFtET0NVTUVOVF1cbiAgICB9XG4gIF07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwcm92aWRlQW5ndWxhclNlcmlhbFRlc3QocmVzcG9uc2VGdW5jdGlvbj86IChpbnB1dDogc3RyaW5nKSA9PiBzdHJpbmcpOiBQcm92aWRlcltdIHtcbiAgcmV0dXJuIFtcbiAgICBOZ3hXZWJTZXJpYWxTZXJ2aWNlLFxuICAgIHtcbiAgICAgIHByb3ZpZGU6ICdTZXJpYWwnLFxuICAgICAgdXNlRmFjdG9yeTogKCkgPT4gbmV3IE1vY2tTZXJpYWwocmVzcG9uc2VGdW5jdGlvbiB8fCAoKGlucHV0OiBzdHJpbmcpID0+IGlucHV0KSksXG4gICAgICBkZXBzOiBbXVxuICAgIH0gYXMgRmFjdG9yeVByb3ZpZGVyXG4gIF07XG59XG4iXX0=
|
@@ -0,0 +1,5 @@
|
|
1
|
+
/**
|
2
|
+
* Generated bundle index. Do not edit.
|
3
|
+
*/
|
4
|
+
export * from './public-api';
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXdlYi1zZXJpYWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9wcm9qZWN0cy9uZ3gtd2ViLXNlcmlhbC9zcmMvbmd4LXdlYi1zZXJpYWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSCxjQUFjLGNBQWMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2VuZXJhdGVkIGJ1bmRsZSBpbmRleC4gRG8gbm90IGVkaXQuXG4gKi9cblxuZXhwb3J0ICogZnJvbSAnLi9wdWJsaWMtYXBpJztcbiJdfQ==
|
@@ -0,0 +1,5 @@
|
|
1
|
+
/*
|
2
|
+
* Public API Surface of ngx-web-serial
|
3
|
+
*/
|
4
|
+
export * from './lib/ngx-web-serial.service';
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljLWFwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Byb2plY3RzL25neC13ZWItc2VyaWFsL3NyYy9wdWJsaWMtYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyw4QkFBOEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBQdWJsaWMgQVBJIFN1cmZhY2Ugb2Ygbmd4LXdlYi1zZXJpYWxcbiAqL1xuXG5leHBvcnQgKiBmcm9tICcuL2xpYi9uZ3gtd2ViLXNlcmlhbC5zZXJ2aWNlJztcbiJdfQ==
|
@@ -0,0 +1,165 @@
|
|
1
|
+
import * as i0 from '@angular/core';
|
2
|
+
import { Injectable, Inject } from '@angular/core';
|
3
|
+
import { Subject, BehaviorSubject, Observable, from, throwError, firstValueFrom, interval, filter, map, takeUntil, timer, catchError } from 'rxjs';
|
4
|
+
import { DOCUMENT } from '@angular/common';
|
5
|
+
|
6
|
+
class MockSerial {
|
7
|
+
constructor(responseFunction) {
|
8
|
+
this.readableController = null;
|
9
|
+
this.responseFunction = responseFunction;
|
10
|
+
this.readableStream = new ReadableStream({
|
11
|
+
start: (controller) => {
|
12
|
+
this.readableController = controller;
|
13
|
+
},
|
14
|
+
cancel: () => {
|
15
|
+
this.readableController = null;
|
16
|
+
}
|
17
|
+
});
|
18
|
+
}
|
19
|
+
requestPort(options) {
|
20
|
+
return Promise.resolve({
|
21
|
+
open: () => Promise.resolve(),
|
22
|
+
close: () => this.readableStream.cancel(),
|
23
|
+
readable: this.readableStream,
|
24
|
+
writable: new WritableStream({
|
25
|
+
write: (chunk) => {
|
26
|
+
const input = new TextDecoder().decode(chunk);
|
27
|
+
const response = this.responseFunction(input);
|
28
|
+
if (this.readableController) {
|
29
|
+
this.readableController.enqueue(new TextEncoder().encode(response));
|
30
|
+
}
|
31
|
+
}
|
32
|
+
})
|
33
|
+
});
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
class NgxWebSerialService {
|
38
|
+
constructor(serial, ngZone) {
|
39
|
+
this.serial = serial;
|
40
|
+
this.ngZone = ngZone;
|
41
|
+
this.port = null;
|
42
|
+
this.abortController = null;
|
43
|
+
this.dataStream = null;
|
44
|
+
this.dataSubject = new Subject();
|
45
|
+
this.writer = null;
|
46
|
+
this.connectedSubject = new BehaviorSubject(false);
|
47
|
+
this.sink = {
|
48
|
+
write: (chunk) => {
|
49
|
+
this.ngZone.run(() => {
|
50
|
+
this.dataSubject.next(chunk);
|
51
|
+
});
|
52
|
+
}
|
53
|
+
};
|
54
|
+
}
|
55
|
+
/**
|
56
|
+
* Establishes a connection to a serial port using the Web Serial API.
|
57
|
+
*/
|
58
|
+
open(serialOptions = { baudRate: 9600 }, options) {
|
59
|
+
return new Observable((observer) => {
|
60
|
+
if (!this.serial) {
|
61
|
+
observer.error('Web serial not supported.');
|
62
|
+
return;
|
63
|
+
}
|
64
|
+
this.serial.requestPort(options)
|
65
|
+
.then((port) => {
|
66
|
+
this.port = port;
|
67
|
+
return this.port.open(serialOptions);
|
68
|
+
})
|
69
|
+
.then(() => {
|
70
|
+
if (!this.port?.readable || !this.port?.writable) {
|
71
|
+
observer.error('Port is not readable or writable.');
|
72
|
+
return;
|
73
|
+
}
|
74
|
+
this.connectedSubject.next(true);
|
75
|
+
this.abortController = new AbortController();
|
76
|
+
this.dataStream = new WritableStream(this.sink);
|
77
|
+
this.writer = this.port?.writable.getWriter();
|
78
|
+
observer.next();
|
79
|
+
return this.port.readable
|
80
|
+
.pipeThrough(new TextDecoderStream())
|
81
|
+
.pipeTo(this.dataStream, { signal: this.abortController.signal })
|
82
|
+
.catch(() => this.closePort().catch((err) => observer.error(err)));
|
83
|
+
})
|
84
|
+
.catch((err) => observer.error(err))
|
85
|
+
.finally(() => observer.complete());
|
86
|
+
});
|
87
|
+
}
|
88
|
+
isConnected() {
|
89
|
+
return this.connectedSubject.asObservable();
|
90
|
+
}
|
91
|
+
read() {
|
92
|
+
return this.dataSubject.asObservable();
|
93
|
+
}
|
94
|
+
write(data) {
|
95
|
+
if (this.writer) {
|
96
|
+
return from(this.writer.write(new TextEncoder().encode(data)));
|
97
|
+
}
|
98
|
+
return throwError(() => new Error('No writer available.'));
|
99
|
+
}
|
100
|
+
waitForReadableUnlock(period = 50, timeout = 5000) {
|
101
|
+
return firstValueFrom(interval(period).pipe(filter(() => !this.port?.readable?.locked), map(() => undefined), takeUntil(timer(timeout)), catchError(() => throwError(() => new Error('Timeout waiting for readable stream to unlock')))));
|
102
|
+
}
|
103
|
+
closePort() {
|
104
|
+
this.abortController = null;
|
105
|
+
if (this.writer) {
|
106
|
+
this.writer.releaseLock();
|
107
|
+
this.writer = null;
|
108
|
+
}
|
109
|
+
if (this.port) {
|
110
|
+
return this.waitForReadableUnlock()
|
111
|
+
.then(() => this.port.close())
|
112
|
+
.then(() => {
|
113
|
+
this.port = null;
|
114
|
+
this.connectedSubject.next(false);
|
115
|
+
});
|
116
|
+
}
|
117
|
+
else {
|
118
|
+
return Promise.resolve();
|
119
|
+
}
|
120
|
+
}
|
121
|
+
close() {
|
122
|
+
if (this.abortController) {
|
123
|
+
this.abortController.abort();
|
124
|
+
}
|
125
|
+
}
|
126
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgxWebSerialService, deps: [{ token: 'Serial' }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
127
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgxWebSerialService }); }
|
128
|
+
}
|
129
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: NgxWebSerialService, decorators: [{
|
130
|
+
type: Injectable
|
131
|
+
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
132
|
+
type: Inject,
|
133
|
+
args: ['Serial']
|
134
|
+
}] }, { type: i0.NgZone }] });
|
135
|
+
function provideAngularSerial() {
|
136
|
+
return [
|
137
|
+
NgxWebSerialService,
|
138
|
+
{
|
139
|
+
provide: 'Serial',
|
140
|
+
useFactory: (document) => document.defaultView?.navigator?.serial,
|
141
|
+
deps: [DOCUMENT]
|
142
|
+
}
|
143
|
+
];
|
144
|
+
}
|
145
|
+
function provideAngularSerialTest(responseFunction) {
|
146
|
+
return [
|
147
|
+
NgxWebSerialService,
|
148
|
+
{
|
149
|
+
provide: 'Serial',
|
150
|
+
useFactory: () => new MockSerial(responseFunction || ((input) => input)),
|
151
|
+
deps: []
|
152
|
+
}
|
153
|
+
];
|
154
|
+
}
|
155
|
+
|
156
|
+
/*
|
157
|
+
* Public API Surface of ngx-web-serial
|
158
|
+
*/
|
159
|
+
|
160
|
+
/**
|
161
|
+
* Generated bundle index. Do not edit.
|
162
|
+
*/
|
163
|
+
|
164
|
+
export { NgxWebSerialService, provideAngularSerial, provideAngularSerialTest };
|
165
|
+
//# sourceMappingURL=ngx-web-serial.mjs.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"ngx-web-serial.mjs","sources":["../../../projects/ngx-web-serial/src/lib/mock-serial.ts","../../../projects/ngx-web-serial/src/lib/ngx-web-serial.service.ts","../../../projects/ngx-web-serial/src/public-api.ts","../../../projects/ngx-web-serial/src/ngx-web-serial.ts"],"sourcesContent":["export class MockSerial {\n private readableController: ReadableStreamDefaultController<Uint8Array> | null = null;\n readonly responseFunction: (input: string) => string;\n readonly readableStream: ReadableStream<Uint8Array>;\n constructor(responseFunction: (input: string) => string) {\n this.responseFunction = responseFunction;\n this.readableStream = new ReadableStream({\n start: (controller) => {\n this.readableController = controller;\n },\n cancel: () => {\n this.readableController = null;\n }\n });\n }\n\n requestPort(options?: SerialPortRequestOptions): Promise<SerialPort> {\n return Promise.resolve({\n open: () => Promise.resolve(),\n close: () => this.readableStream.cancel(),\n readable: this.readableStream,\n writable: new WritableStream({\n write: (chunk) => {\n const input = new TextDecoder().decode(chunk);\n const response = this.responseFunction(input);\n if (this.readableController) {\n this.readableController.enqueue(new TextEncoder().encode(response));\n }\n }\n })\n } as any as SerialPort);\n }\n}\n","import { FactoryProvider, Inject, Injectable, NgZone, Provider } from '@angular/core';\nimport {\n BehaviorSubject,\n catchError,\n filter,\n firstValueFrom,\n from,\n interval,\n map,\n Observable,\n Subject,\n Subscriber,\n takeUntil,\n throwError,\n timer\n} from 'rxjs';\nimport { DOCUMENT } from '@angular/common';\nimport { MockSerial } from './mock-serial';\n\n@Injectable()\nexport class NgxWebSerialService {\n\n private port: SerialPort | null = null;\n private abortController: AbortController | null = null;\n private dataStream: WritableStream | null = null;\n private dataSubject: Subject<string> = new Subject<string>();\n private writer: WritableStreamDefaultWriter<Uint8Array> | null = null;\n private connectedSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);\n\n private readonly sink: UnderlyingSink = {\n write: (chunk: any) => {\n this.ngZone.run(() => {\n this.dataSubject.next(chunk);\n });\n }\n }\n\n constructor(\n @Inject('Serial') readonly serial: Serial | undefined,\n private ngZone: NgZone\n ) {\n }\n\n /**\n * Establishes a connection to a serial port using the Web Serial API.\n */\n open(serialOptions: SerialOptions = { baudRate: 9600 }, options?: SerialPortRequestOptions): Observable<void> {\n return new Observable<void>((observer: Subscriber<void>) => {\n if (!this.serial) {\n observer.error('Web serial not supported.');\n return;\n }\n this.serial.requestPort(options)\n .then((port: SerialPort) => {\n this.port = port;\n return this.port.open(serialOptions);\n })\n .then(() => {\n if (!this.port?.readable || !this.port?.writable) {\n observer.error('Port is not readable or writable.');\n return;\n }\n this.connectedSubject.next(true);\n this.abortController = new AbortController();\n this.dataStream = new WritableStream(this.sink);\n this.writer = this.port?.writable.getWriter();\n observer.next();\n return this.port.readable\n .pipeThrough(new TextDecoderStream())\n .pipeTo(this.dataStream, {signal: this.abortController.signal})\n .catch(() => this.closePort().catch((err) => observer.error(err)));\n })\n .catch((err) => observer.error(err))\n .finally(() => observer.complete());\n });\n }\n\n isConnected(): Observable<boolean> {\n return this.connectedSubject.asObservable();\n }\n\n read(): Observable<string> {\n return this.dataSubject.asObservable();\n }\n\n write(data: string): Observable<void> {\n if (this.writer) {\n return from(this.writer.write(new TextEncoder().encode(data)));\n\n }\n return throwError(() => new Error('No writer available.'));\n }\n\n\n private waitForReadableUnlock(period: number = 50, timeout: number = 5000): Promise<void> {\n return firstValueFrom(interval(period).pipe(\n filter(() => !this.port?.readable?.locked),\n map(() => undefined),\n takeUntil(timer(timeout)),\n catchError(() => throwError(() => new Error('Timeout waiting for readable stream to unlock')))\n ));\n }\n\n private closePort(): Promise<void> {\n this.abortController = null;\n if (this.writer) {\n this.writer.releaseLock();\n this.writer = null;\n }\n if (this.port) {\n return this.waitForReadableUnlock()\n .then(() => this.port!.close())\n .then(() => {\n this.port = null;\n this.connectedSubject.next(false);\n });\n } else {\n return Promise.resolve();\n }\n }\n close(): void {\n if (this.abortController) {\n this.abortController.abort();\n }\n }\n}\n\nexport function provideAngularSerial(): Provider[] {\n return [\n NgxWebSerialService,\n {\n provide: 'Serial',\n useFactory: (document: Document) => document.defaultView?.navigator?.serial,\n deps: [DOCUMENT]\n }\n ];\n}\n\nexport function provideAngularSerialTest(responseFunction?: (input: string) => string): Provider[] {\n return [\n NgxWebSerialService,\n {\n provide: 'Serial',\n useFactory: () => new MockSerial(responseFunction || ((input: string) => input)),\n deps: []\n } as FactoryProvider\n ];\n}\n","/*\n * Public API Surface of ngx-web-serial\n */\n\nexport * from './lib/ngx-web-serial.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/index.d.ts
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
/// <reference types="w3c-web-serial" />
|
2
|
+
export declare class MockSerial {
|
3
|
+
private readableController;
|
4
|
+
readonly responseFunction: (input: string) => string;
|
5
|
+
readonly readableStream: ReadableStream<Uint8Array>;
|
6
|
+
constructor(responseFunction: (input: string) => string);
|
7
|
+
requestPort(options?: SerialPortRequestOptions): Promise<SerialPort>;
|
8
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
/// <reference types="w3c-web-serial" />
|
2
|
+
import { NgZone, Provider } from '@angular/core';
|
3
|
+
import { Observable } from 'rxjs';
|
4
|
+
import * as i0 from "@angular/core";
|
5
|
+
export declare class NgxWebSerialService {
|
6
|
+
readonly serial: Serial | undefined;
|
7
|
+
private ngZone;
|
8
|
+
private port;
|
9
|
+
private abortController;
|
10
|
+
private dataStream;
|
11
|
+
private dataSubject;
|
12
|
+
private writer;
|
13
|
+
private connectedSubject;
|
14
|
+
private readonly sink;
|
15
|
+
constructor(serial: Serial | undefined, ngZone: NgZone);
|
16
|
+
/**
|
17
|
+
* Establishes a connection to a serial port using the Web Serial API.
|
18
|
+
*/
|
19
|
+
open(serialOptions?: SerialOptions, options?: SerialPortRequestOptions): Observable<void>;
|
20
|
+
isConnected(): Observable<boolean>;
|
21
|
+
read(): Observable<string>;
|
22
|
+
write(data: string): Observable<void>;
|
23
|
+
private waitForReadableUnlock;
|
24
|
+
private closePort;
|
25
|
+
close(): void;
|
26
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NgxWebSerialService, never>;
|
27
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<NgxWebSerialService>;
|
28
|
+
}
|
29
|
+
export declare function provideAngularSerial(): Provider[];
|
30
|
+
export declare function provideAngularSerialTest(responseFunction?: (input: string) => string): Provider[];
|
package/package.json
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
{
|
2
|
+
"name": "ngx-web-serial",
|
3
|
+
"version": "0.0.1",
|
4
|
+
"peerDependencies": {
|
5
|
+
"@angular/common": "^17.3.0",
|
6
|
+
"@angular/core": "^17.3.0"
|
7
|
+
},
|
8
|
+
"dependencies": {
|
9
|
+
"tslib": "^2.3.0"
|
10
|
+
},
|
11
|
+
"sideEffects": false,
|
12
|
+
"module": "fesm2022/ngx-web-serial.mjs",
|
13
|
+
"typings": "index.d.ts",
|
14
|
+
"exports": {
|
15
|
+
"./package.json": {
|
16
|
+
"default": "./package.json"
|
17
|
+
},
|
18
|
+
".": {
|
19
|
+
"types": "./index.d.ts",
|
20
|
+
"esm2022": "./esm2022/ngx-web-serial.mjs",
|
21
|
+
"esm": "./esm2022/ngx-web-serial.mjs",
|
22
|
+
"default": "./fesm2022/ngx-web-serial.mjs"
|
23
|
+
}
|
24
|
+
}
|
25
|
+
}
|
package/public-api.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export * from './lib/ngx-web-serial.service';
|