@gurezo/web-serial-rxjs 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.ja.md +5 -510
  2. package/README.md +5 -509
  3. package/package.json +2 -2
package/README.ja.md CHANGED
@@ -7,11 +7,8 @@ Web Serial API を RxJS ベースのリアクティブなラッパーで提供
7
7
  - [機能](#機能)
8
8
  - [ブラウザサポート](#ブラウザサポート)
9
9
  - [インストール](#インストール)
10
- - [クイックスタート](#クイックスタート)
11
- - [使用例](#使用例)
12
- - [API リファレンス](#api-リファレンス)
10
+ - [ドキュメント](#ドキュメント)
13
11
  - [フレームワーク別の例](#フレームワーク別の例)
14
- - [高度な使用方法](#高度な使用方法)
15
12
  - [貢献](#貢献)
16
13
  - [ライセンス](#ライセンス)
17
14
  - [リンク](#リンク)
@@ -56,408 +53,11 @@ pnpm add rxjs
56
53
 
57
54
  **最小要件バージョン**: RxJS ^7.8.0
58
55
 
59
- ## クイックスタート
56
+ ## ドキュメント
60
57
 
61
- 簡単な使用例:
62
-
63
- ```typescript
64
- import {
65
- createSerialClient,
66
- isBrowserSupported,
67
- } from '@gurezo/web-serial-rxjs';
68
-
69
- // ブラウザサポートをチェック
70
- if (!isBrowserSupported()) {
71
- console.error('このブラウザは Web Serial API をサポートしていません');
72
- return;
73
- }
74
-
75
- // シリアルクライアントを作成
76
- const client = createSerialClient({ baudRate: 9600 });
77
-
78
- // シリアルポートに接続
79
- client.connect().subscribe({
80
- next: () => {
81
- console.log('シリアルポートに接続しました');
82
-
83
- // シリアルポートからデータを読み取る
84
- client.getReadStream().subscribe({
85
- next: (data: Uint8Array) => {
86
- const decoder = new TextDecoder('utf-8');
87
- const text = decoder.decode(data);
88
- console.log('受信:', text);
89
- },
90
- error: (error) => {
91
- console.error('読み取りエラー:', error);
92
- },
93
- });
94
-
95
- // シリアルポートにデータを書き込む
96
- const encoder = new TextEncoder();
97
- const data = encoder.encode('Hello, Serial Port!\n');
98
- client.write(data).subscribe({
99
- next: () => console.log('データを書き込みました'),
100
- error: (error) => console.error('書き込みエラー:', error),
101
- });
102
- },
103
- error: (error) => {
104
- console.error('接続エラー:', error);
105
- },
106
- });
107
- ```
108
-
109
- ## 使用例
110
-
111
- ### 基本的な接続
112
-
113
- ```typescript
114
- import { createSerialClient } from '@gurezo/web-serial-rxjs';
115
-
116
- const client = createSerialClient({
117
- baudRate: 115200,
118
- dataBits: 8,
119
- stopBits: 1,
120
- parity: 'none',
121
- });
122
-
123
- // 接続(ユーザーにポート選択を促す)
124
- client.connect().subscribe({
125
- next: () => console.log('接続しました'),
126
- error: (error) => console.error('接続に失敗しました:', error),
127
- });
128
- ```
129
-
130
- ### データの読み取り
131
-
132
- ```typescript
133
- import { createSerialClient } from '@gurezo/web-serial-rxjs';
134
- import { map } from 'rxjs/operators';
135
-
136
- const client = createSerialClient({ baudRate: 9600 });
137
-
138
- client.connect().subscribe({
139
- next: () => {
140
- // データを読み取ってデコード
141
- client
142
- .getReadStream()
143
- .pipe(
144
- map((data: Uint8Array) => {
145
- const decoder = new TextDecoder('utf-8');
146
- return decoder.decode(data);
147
- }),
148
- )
149
- .subscribe({
150
- next: (text) => console.log('受信:', text),
151
- error: (error) => console.error('読み取りエラー:', error),
152
- });
153
- },
154
- });
155
- ```
156
-
157
- ### データの書き込み
158
-
159
- ```typescript
160
- import { createSerialClient } from '@gurezo/web-serial-rxjs';
161
- import { from } from 'rxjs';
162
- import { map } from 'rxjs/operators';
163
-
164
- const client = createSerialClient({ baudRate: 9600 });
165
-
166
- client.connect().subscribe({
167
- next: () => {
168
- // 単一のチャンクを書き込む
169
- const encoder = new TextEncoder();
170
- const data = encoder.encode('Hello\n');
171
- client.write(data).subscribe({
172
- next: () => console.log('書き込みました'),
173
- error: (error) => console.error('書き込みエラー:', error),
174
- });
175
-
176
- // Observable ストリームから書き込む
177
- const messages = ['メッセージ 1\n', 'メッセージ 2\n', 'メッセージ 3\n'];
178
- const dataStream$ = from(messages).pipe(
179
- map((msg) => new TextEncoder().encode(msg)),
180
- );
181
- client.writeStream(dataStream$).subscribe({
182
- next: () => console.log('すべてのメッセージを書き込みました'),
183
- error: (error) => console.error('ストリーム書き込みエラー:', error),
184
- });
185
- },
186
- });
187
- ```
188
-
189
- ### エラーハンドリング
190
-
191
- ```typescript
192
- import {
193
- createSerialClient,
194
- SerialError,
195
- SerialErrorCode,
196
- } from '@gurezo/web-serial-rxjs';
197
-
198
- const client = createSerialClient({ baudRate: 9600 });
199
-
200
- client.connect().subscribe({
201
- next: () => console.log('接続しました'),
202
- error: (error) => {
203
- if (error instanceof SerialError) {
204
- switch (error.code) {
205
- case SerialErrorCode.BROWSER_NOT_SUPPORTED:
206
- console.error('ブラウザが Web Serial API をサポートしていません');
207
- break;
208
- case SerialErrorCode.PORT_NOT_AVAILABLE:
209
- console.error('シリアルポートが利用できません');
210
- break;
211
- case SerialErrorCode.CONNECTION_LOST:
212
- console.error('接続が切断されました');
213
- break;
214
- default:
215
- console.error('シリアルエラー:', error.message);
216
- }
217
- } else {
218
- console.error('不明なエラー:', error);
219
- }
220
- },
221
- });
222
- ```
223
-
224
- ### ポートフィルタリング
225
-
226
- ```typescript
227
- import { createSerialClient } from '@gurezo/web-serial-rxjs';
228
-
229
- // USB ベンダー ID でポートをフィルタリング
230
- const client = createSerialClient({
231
- baudRate: 9600,
232
- filters: [{ usbVendorId: 0x1234 }, { usbVendorId: 0x5678 }],
233
- });
234
-
235
- // 特定のポートをリクエスト
236
- client.requestPort().subscribe({
237
- next: (port) => {
238
- console.log('ポートが選択されました:', port);
239
- // 選択されたポートに接続
240
- client.connect(port).subscribe({
241
- next: () => console.log('フィルタリングされたポートに接続しました'),
242
- error: (error) => console.error('接続エラー:', error),
243
- });
244
- },
245
- error: (error) => console.error('ポートリクエストエラー:', error),
246
- });
247
- ```
248
-
249
- ## API リファレンス
250
-
251
- ### `createSerialClient(options?)`
252
-
253
- 新しい `SerialClient` インスタンスを作成します。
254
-
255
- **パラメータ:**
256
-
257
- - `options?` (オプション): `SerialClientOptions` - シリアルクライアントの設定オプション
258
-
259
- **戻り値:** `SerialClient` - 新しい SerialClient インスタンス
260
-
261
- **例:**
262
-
263
- ```typescript
264
- const client = createSerialClient({
265
- baudRate: 9600,
266
- dataBits: 8,
267
- stopBits: 1,
268
- parity: 'none',
269
- });
270
- ```
271
-
272
- ### `SerialClient` インターフェース
273
-
274
- シリアルポートと対話するためのメインインターフェースです。
275
-
276
- #### メソッド
277
-
278
- ##### `requestPort(): Observable<SerialPort>`
279
-
280
- ユーザーからシリアルポートをリクエストします。ポート選択のためのブラウザダイアログを開きます。
281
-
282
- **戻り値:** `Observable<SerialPort>` - 選択された `SerialPort` インスタンスを発行
283
-
284
- ##### `getPorts(): Observable<SerialPort[]>`
285
-
286
- ユーザーが以前にアクセスを許可したすべての利用可能なシリアルポートを取得します。
287
-
288
- **戻り値:** `Observable<SerialPort[]>` - 利用可能な `SerialPort` インスタンスの配列を発行
289
-
290
- ##### `connect(port?: SerialPort): Observable<void>`
291
-
292
- シリアルポートに接続します。ポートが提供されない場合、ユーザーにリクエストします。
293
-
294
- **パラメータ:**
295
-
296
- - `port?` (オプション): `SerialPort` - 接続するポート
297
-
298
- **戻り値:** `Observable<void>` - ポートが開かれたときに完了
299
-
300
- ##### `disconnect(): Observable<void>`
301
-
302
- シリアルポートから切断します。
303
-
304
- **戻り値:** `Observable<void>` - ポートが閉じられたときに完了
305
-
306
- ##### `getReadStream(): Observable<Uint8Array>`
307
-
308
- シリアルポートから読み取ったデータを発行する Observable を取得します。
309
-
310
- **戻り値:** `Observable<Uint8Array>` - データが受信されると `Uint8Array` チャンクを発行
311
-
312
- ##### `writeStream(data$: Observable<Uint8Array>): Observable<void>`
313
-
314
- Observable ストリームからシリアルポートにデータを書き込みます。
315
-
316
- **パラメータ:**
317
-
318
- - `data$`: `Observable<Uint8Array>` - 書き込む `Uint8Array` チャンクを発行する Observable
319
-
320
- **戻り値:** `Observable<void>` - 書き込みが完了したときに完了
321
-
322
- ##### `write(data: Uint8Array): Observable<void>`
323
-
324
- シリアルポートに単一のデータチャンクを書き込みます。
325
-
326
- **パラメータ:**
327
-
328
- - `data`: `Uint8Array` - 書き込むデータ
329
-
330
- **戻り値:** `Observable<void>` - データが書き込まれたときに完了
331
-
332
- #### プロパティ
333
-
334
- - `connected: boolean` - ポートが現在開いているかどうかを示す読み取り専用プロパティ
335
- - `currentPort: SerialPort | null` - 現在の `SerialPort` インスタンス、または接続されていない場合は `null` の読み取り専用プロパティ
336
-
337
- ### `SerialClientOptions` インターフェース
338
-
339
- `SerialClient` を作成するための設定オプションです。
340
-
341
- ```typescript
342
- interface SerialClientOptions {
343
- baudRate?: number; // デフォルト: 9600
344
- dataBits?: 7 | 8; // デフォルト: 8
345
- stopBits?: 1 | 2; // デフォルト: 1
346
- parity?: 'none' | 'even' | 'odd'; // デフォルト: 'none'
347
- bufferSize?: number; // デフォルト: 255
348
- flowControl?: 'none' | 'hardware'; // デフォルト: 'none'
349
- filters?: SerialPortFilter[]; // オプションのポートフィルター
350
- }
351
- ```
352
-
353
- **オプション:**
354
-
355
- - `baudRate` (オプション): 通信速度(ビット/秒)。デフォルト: `9600`
356
- - `dataBits` (オプション): 文字あたりのデータビット数。`7` または `8`。デフォルト: `8`
357
- - `stopBits` (オプション): ストップビット数。`1` または `2`。デフォルト: `1`
358
- - `parity` (オプション): パリティチェックモード。`'none'`、`'even'`、または `'odd'`。デフォルト: `'none'`
359
- - `bufferSize` (オプション): 読み取りバッファのサイズ。デフォルト: `255`
360
- - `flowControl` (オプション): フロー制御モード。`'none'` または `'hardware'`。デフォルト: `'none'`
361
- - `filters` (オプション): 利用可能なポートをフィルタリングする `SerialPortFilter` オブジェクトの配列
362
-
363
- ### エラーハンドリング
364
-
365
- #### `SerialError` クラス
366
-
367
- シリアルポート操作のためのカスタムエラークラスです。
368
-
369
- ```typescript
370
- class SerialError extends Error {
371
- readonly code: SerialErrorCode;
372
- readonly originalError?: Error;
373
-
374
- is(code: SerialErrorCode): boolean;
375
- }
376
- ```
377
-
378
- **プロパティ:**
379
-
380
- - `code`: `SerialErrorCode` - エラーコード
381
- - `originalError?`: `Error` - このエラーを引き起こした元のエラー(存在する場合)
382
-
383
- **メソッド:**
384
-
385
- - `is(code: SerialErrorCode): boolean` - エラーが特定のエラーコードと一致するかチェック
386
-
387
- #### `SerialErrorCode` 列挙型
388
-
389
- さまざまなタイプのシリアルポートエラーのエラーコード:
390
-
391
- - `BROWSER_NOT_SUPPORTED` - ブラウザが Web Serial API をサポートしていない
392
- - `PORT_NOT_AVAILABLE` - シリアルポートが利用できない
393
- - `PORT_OPEN_FAILED` - シリアルポートを開くのに失敗した
394
- - `PORT_ALREADY_OPEN` - シリアルポートは既に開いている
395
- - `PORT_NOT_OPEN` - シリアルポートが開いていない
396
- - `READ_FAILED` - シリアルポートからの読み取りに失敗した
397
- - `WRITE_FAILED` - シリアルポートへの書き込みに失敗した
398
- - `CONNECTION_LOST` - シリアルポート接続が切断された
399
- - `INVALID_FILTER_OPTIONS` - 無効なフィルターオプション
400
- - `OPERATION_CANCELLED` - 操作がキャンセルされた
401
- - `UNKNOWN` - 不明なエラー
402
-
403
- ### ブラウザ検出ユーティリティ
404
-
405
- #### `isBrowserSupported(): boolean`
406
-
407
- ブラウザが Web Serial API をサポートしているかチェックします(例外を投げないバージョン)。
408
-
409
- **戻り値:** `boolean` - サポートされている場合は `true`、それ以外は `false`
410
-
411
- #### `checkBrowserSupport(): void`
412
-
413
- ブラウザが Web Serial API をサポートしているかチェックします。サポートされていない場合は `SerialError` を投げます。
414
-
415
- **例外:** Web Serial API をサポートしていない場合、`BROWSER_NOT_SUPPORTED` コードを持つ `SerialError` を投げます
416
-
417
- #### `detectBrowserType(): BrowserType`
418
-
419
- ユーザーエージェントからブラウザタイプを検出します。
420
-
421
- **戻り値:** `BrowserType` - `CHROME`、`EDGE`、`OPERA`、または `UNKNOWN` のいずれか
422
-
423
- #### `hasWebSerialSupport(): boolean`
424
-
425
- 機能検出を使用してブラウザが Web Serial API サポートを持っているかチェックします。
426
-
427
- **戻り値:** `boolean` - Web Serial API が利用可能な場合は `true`、それ以外は `false`
428
-
429
- ### I/O ユーティリティ
430
-
431
- #### `readableToObservable(stream: ReadableStream<Uint8Array>): Observable<Uint8Array>`
432
-
433
- `ReadableStream` を RxJS `Observable` に変換します。
434
-
435
- **パラメータ:**
436
-
437
- - `stream`: `ReadableStream<Uint8Array>` - 変換するストリーム
438
-
439
- **戻り値:** `Observable<Uint8Array>` - データチャンクを発行する Observable
440
-
441
- #### `observableToWritable(observable: Observable<Uint8Array>): WritableStream<Uint8Array>`
442
-
443
- RxJS `Observable` を `WritableStream` に変換します。
444
-
445
- **パラメータ:**
446
-
447
- - `observable`: `Observable<Uint8Array>` - 変換する observable
448
-
449
- **戻り値:** `WritableStream<Uint8Array>` - observable からデータを書き込む書き込み可能なストリーム
450
-
451
- #### `subscribeToWritable(observable: Observable<Uint8Array>, stream: WritableStream<Uint8Array>): { unsubscribe: () => void }`
452
-
453
- Observable を購読し、その値を WritableStream に書き込みます。
454
-
455
- **パラメータ:**
456
-
457
- - `observable`: `Observable<Uint8Array>` - 購読する observable
458
- - `stream`: `WritableStream<Uint8Array>` - 書き込むストリーム
459
-
460
- **戻り値:** `unsubscribe()` メソッドを持つ購読オブジェクト
58
+ - **[クイックスタート](docs/QUICK_START.ja.md)** - 基本的な例と使用方法のパターンで始める
59
+ - **[API リファレンス](docs/API_REFERENCE.ja.md)** - 詳細な説明を含む完全な API ドキュメント
60
+ - **[高度な使用方法](docs/ADVANCED_USAGE.ja.md)** - 高度なパターン、ストリーム処理、エラー回復
461
61
 
462
62
  ## フレームワーク別の例
463
63
 
@@ -472,111 +72,6 @@ Observable を購読し、その値を WritableStream に書き込みます。
472
72
 
473
73
  各例には、セットアップと使用方法の説明を含む README が含まれています。
474
74
 
475
- ## 高度な使用方法
476
-
477
- ### Observable パターン
478
-
479
- RxJS オペレーターを使用してシリアルデータを処理できます:
480
-
481
- ```typescript
482
- import { map, filter, bufferTime } from 'rxjs/operators';
483
-
484
- client
485
- .getReadStream()
486
- .pipe(
487
- map((data: Uint8Array) => {
488
- const decoder = new TextDecoder('utf-8');
489
- return decoder.decode(data);
490
- }),
491
- filter((text) => text.trim().length > 0),
492
- bufferTime(1000), // 1 秒間メッセージをバッファリング
493
- )
494
- .subscribe({
495
- next: (messages) => {
496
- console.log('バッファリングされたメッセージ:', messages);
497
- },
498
- });
499
- ```
500
-
501
- ### ストリーム処理
502
-
503
- RxJS オペレーターでデータストリームを処理:
504
-
505
- ```typescript
506
- import { map, scan, debounceTime } from 'rxjs/operators';
507
-
508
- // 受信データを累積
509
- client
510
- .getReadStream()
511
- .pipe(
512
- map((data: Uint8Array) => {
513
- const decoder = new TextDecoder('utf-8');
514
- return decoder.decode(data);
515
- }),
516
- scan((acc, current) => acc + current, ''),
517
- debounceTime(500),
518
- )
519
- .subscribe({
520
- next: (accumulated) => {
521
- console.log('累積データ:', accumulated);
522
- },
523
- });
524
- ```
525
-
526
- ### カスタムフィルター
527
-
528
- ポートフィルターを使用して利用可能なポートを制限:
529
-
530
- ```typescript
531
- const client = createSerialClient({
532
- baudRate: 9600,
533
- filters: [
534
- { usbVendorId: 0x1234, usbProductId: 0x5678 },
535
- { usbVendorId: 0xabcd },
536
- ],
537
- });
538
- ```
539
-
540
- ### エラー回復
541
-
542
- エラー回復パターンを実装:
543
-
544
- ```typescript
545
- import { retry, catchError } from 'rxjs/operators';
546
- import { of } from 'rxjs';
547
-
548
- client
549
- .getReadStream()
550
- .pipe(
551
- retry({
552
- count: 3,
553
- delay: 1000,
554
- }),
555
- catchError((error) => {
556
- console.error('リトライ後も失敗:', error);
557
- return of(null); // 空の observable を返す
558
- }),
559
- )
560
- .subscribe({
561
- next: (data) => {
562
- if (data) {
563
- console.log('受信:', data);
564
- }
565
- },
566
- });
567
- ```
568
-
569
- ## 開発とリリース戦略
570
-
571
- このプロジェクトは**trunk-based開発**アプローチに従います:
572
-
573
- - **`main`ブランチ**: 常にリリース可能な状態
574
- - **短命ブランチ**: `feature/*`, `fix/*`, `docs/*` はプルリクエスト用
575
- - **リリース**: ブランチではなくGitタグ(例: `v1.0.0`)で管理
576
- - **バージョン保守**: 複数のメジャーバージョンを保守する必要がある場合のみ `release/v*` ブランチを追加
577
-
578
- 詳細な貢献ガイドラインについては、[CONTRIBUTING.ja.md](https://github.com/gurezo/web-serial-rxjs/blob/main/CONTRIBUTING.ja.md) を参照してください。
579
-
580
75
  ## 貢献
581
76
 
582
77
  貢献を歓迎します!詳細については、[貢献ガイド](https://github.com/gurezo/web-serial-rxjs/blob/main/CONTRIBUTING.ja.md)を参照してください:
package/README.md CHANGED
@@ -7,11 +7,8 @@ A TypeScript library that provides a reactive RxJS-based wrapper for the Web Ser
7
7
  - [Features](#features)
8
8
  - [Browser Support](#browser-support)
9
9
  - [Installation](#installation)
10
- - [Quick Start](#quick-start)
11
- - [Usage Examples](#usage-examples)
12
- - [API Reference](#api-reference)
10
+ - [Documentation](#documentation)
13
11
  - [Framework Examples](#framework-examples)
14
- - [Advanced Usage](#advanced-usage)
15
12
  - [Contributing](#contributing)
16
13
  - [License](#license)
17
14
  - [Links](#links)
@@ -56,407 +53,11 @@ pnpm add rxjs
56
53
 
57
54
  **Minimum required version**: RxJS ^7.8.0
58
55
 
59
- ## Quick Start
56
+ ## Documentation
60
57
 
61
- Here's a simple example to get you started:
62
-
63
- ```typescript
64
- import {
65
- createSerialClient,
66
- isBrowserSupported,
67
- } from '@gurezo/web-serial-rxjs';
68
-
69
- // Check browser support
70
- if (!isBrowserSupported()) {
71
- console.error('Web Serial API is not supported in this browser');
72
- return;
73
- }
74
-
75
- // Create a serial client
76
- const client = createSerialClient({ baudRate: 9600 });
77
-
78
- // Connect to a serial port
79
- client.connect().subscribe({
80
- next: () => {
81
- console.log('Connected to serial port');
82
-
83
- // Read data from the serial port
84
- client.getReadStream().subscribe({
85
- next: (data: Uint8Array) => {
86
- const decoder = new TextDecoder('utf-8');
87
- const text = decoder.decode(data);
88
- console.log('Received:', text);
89
- },
90
- error: (error) => {
91
- console.error('Read error:', error);
92
- },
93
- });
94
-
95
- // Write data to the serial port
96
- const encoder = new TextEncoder();
97
- const data = encoder.encode('Hello, Serial Port!\n');
98
- client.write(data).subscribe({
99
- next: () => console.log('Data written'),
100
- error: (error) => console.error('Write error:', error),
101
- });
102
- },
103
- error: (error) => {
104
- console.error('Connection error:', error);
105
- },
106
- });
107
- ```
108
-
109
- ## Usage Examples
110
-
111
- ### Basic Connection
112
-
113
- ```typescript
114
- import { createSerialClient } from '@gurezo/web-serial-rxjs';
115
-
116
- const client = createSerialClient({
117
- baudRate: 115200,
118
- dataBits: 8,
119
- stopBits: 1,
120
- parity: 'none',
121
- });
122
-
123
- // Connect (will prompt user to select a port)
124
- client.connect().subscribe({
125
- next: () => console.log('Connected'),
126
- error: (error) => console.error('Connection failed:', error),
127
- });
128
- ```
129
-
130
- ### Reading Data
131
-
132
- ```typescript
133
- import { createSerialClient } from '@gurezo/web-serial-rxjs';
134
- import { map } from 'rxjs/operators';
135
-
136
- const client = createSerialClient({ baudRate: 9600 });
137
-
138
- client.connect().subscribe({
139
- next: () => {
140
- // Read and decode data
141
- client
142
- .getReadStream()
143
- .pipe(
144
- map((data: Uint8Array) => {
145
- const decoder = new TextDecoder('utf-8');
146
- return decoder.decode(data);
147
- }),
148
- )
149
- .subscribe({
150
- next: (text) => console.log('Received:', text),
151
- error: (error) => console.error('Read error:', error),
152
- });
153
- },
154
- });
155
- ```
156
-
157
- ### Writing Data
158
-
159
- ```typescript
160
- import { createSerialClient } from '@gurezo/web-serial-rxjs';
161
- import { from } from 'rxjs';
162
-
163
- const client = createSerialClient({ baudRate: 9600 });
164
-
165
- client.connect().subscribe({
166
- next: () => {
167
- // Write a single chunk
168
- const encoder = new TextEncoder();
169
- const data = encoder.encode('Hello\n');
170
- client.write(data).subscribe({
171
- next: () => console.log('Written'),
172
- error: (error) => console.error('Write error:', error),
173
- });
174
-
175
- // Write from an Observable stream
176
- const messages = ['Message 1\n', 'Message 2\n', 'Message 3\n'];
177
- const dataStream$ = from(messages).pipe(
178
- map((msg) => new TextEncoder().encode(msg)),
179
- );
180
- client.writeStream(dataStream$).subscribe({
181
- next: () => console.log('All messages written'),
182
- error: (error) => console.error('Stream write error:', error),
183
- });
184
- },
185
- });
186
- ```
187
-
188
- ### Error Handling
189
-
190
- ```typescript
191
- import {
192
- createSerialClient,
193
- SerialError,
194
- SerialErrorCode,
195
- } from '@gurezo/web-serial-rxjs';
196
-
197
- const client = createSerialClient({ baudRate: 9600 });
198
-
199
- client.connect().subscribe({
200
- next: () => console.log('Connected'),
201
- error: (error) => {
202
- if (error instanceof SerialError) {
203
- switch (error.code) {
204
- case SerialErrorCode.BROWSER_NOT_SUPPORTED:
205
- console.error('Browser does not support Web Serial API');
206
- break;
207
- case SerialErrorCode.PORT_NOT_AVAILABLE:
208
- console.error('Serial port is not available');
209
- break;
210
- case SerialErrorCode.CONNECTION_LOST:
211
- console.error('Connection lost');
212
- break;
213
- default:
214
- console.error('Serial error:', error.message);
215
- }
216
- } else {
217
- console.error('Unknown error:', error);
218
- }
219
- },
220
- });
221
- ```
222
-
223
- ### Port Filtering
224
-
225
- ```typescript
226
- import { createSerialClient } from '@gurezo/web-serial-rxjs';
227
-
228
- // Filter ports by USB vendor ID
229
- const client = createSerialClient({
230
- baudRate: 9600,
231
- filters: [{ usbVendorId: 0x1234 }, { usbVendorId: 0x5678 }],
232
- });
233
-
234
- // Request a specific port
235
- client.requestPort().subscribe({
236
- next: (port) => {
237
- console.log('Port selected:', port);
238
- // Connect to the selected port
239
- client.connect(port).subscribe({
240
- next: () => console.log('Connected to filtered port'),
241
- error: (error) => console.error('Connection error:', error),
242
- });
243
- },
244
- error: (error) => console.error('Port request error:', error),
245
- });
246
- ```
247
-
248
- ## API Reference
249
-
250
- ### `createSerialClient(options?)`
251
-
252
- Creates a new `SerialClient` instance.
253
-
254
- **Parameters:**
255
-
256
- - `options?` (optional): `SerialClientOptions` - Configuration options for the serial client
257
-
258
- **Returns:** `SerialClient` - A new SerialClient instance
259
-
260
- **Example:**
261
-
262
- ```typescript
263
- const client = createSerialClient({
264
- baudRate: 9600,
265
- dataBits: 8,
266
- stopBits: 1,
267
- parity: 'none',
268
- });
269
- ```
270
-
271
- ### `SerialClient` Interface
272
-
273
- The main interface for interacting with serial ports.
274
-
275
- #### Methods
276
-
277
- ##### `requestPort(): Observable<SerialPort>`
278
-
279
- Requests a serial port from the user. Opens a browser dialog for port selection.
280
-
281
- **Returns:** `Observable<SerialPort>` - Emits the selected `SerialPort` instance
282
-
283
- ##### `getPorts(): Observable<SerialPort[]>`
284
-
285
- Gets all available serial ports that the user has previously granted access to.
286
-
287
- **Returns:** `Observable<SerialPort[]>` - Emits an array of available `SerialPort` instances
288
-
289
- ##### `connect(port?: SerialPort): Observable<void>`
290
-
291
- Connects to a serial port. If no port is provided, will request one from the user.
292
-
293
- **Parameters:**
294
-
295
- - `port?` (optional): `SerialPort` - The port to connect to
296
-
297
- **Returns:** `Observable<void>` - Completes when the port is opened
298
-
299
- ##### `disconnect(): Observable<void>`
300
-
301
- Disconnects from the serial port.
302
-
303
- **Returns:** `Observable<void>` - Completes when the port is closed
304
-
305
- ##### `getReadStream(): Observable<Uint8Array>`
306
-
307
- Gets an Observable that emits data read from the serial port.
308
-
309
- **Returns:** `Observable<Uint8Array>` - Emits `Uint8Array` chunks as data is received
310
-
311
- ##### `writeStream(data$: Observable<Uint8Array>): Observable<void>`
312
-
313
- Writes data to the serial port from an Observable stream.
314
-
315
- **Parameters:**
316
-
317
- - `data$`: `Observable<Uint8Array>` - Observable that emits `Uint8Array` chunks to write
318
-
319
- **Returns:** `Observable<void>` - Completes when writing is finished
320
-
321
- ##### `write(data: Uint8Array): Observable<void>`
322
-
323
- Writes a single chunk of data to the serial port.
324
-
325
- **Parameters:**
326
-
327
- - `data`: `Uint8Array` - Data to write
328
-
329
- **Returns:** `Observable<void>` - Completes when the data is written
330
-
331
- #### Properties
332
-
333
- - `connected: boolean` - Read-only property indicating if the port is currently open
334
- - `currentPort: SerialPort | null` - Read-only property with the current `SerialPort` instance, or `null` if not connected
335
-
336
- ### `SerialClientOptions` Interface
337
-
338
- Configuration options for creating a `SerialClient`.
339
-
340
- ```typescript
341
- interface SerialClientOptions {
342
- baudRate?: number; // Default: 9600
343
- dataBits?: 7 | 8; // Default: 8
344
- stopBits?: 1 | 2; // Default: 1
345
- parity?: 'none' | 'even' | 'odd'; // Default: 'none'
346
- bufferSize?: number; // Default: 255
347
- flowControl?: 'none' | 'hardware'; // Default: 'none'
348
- filters?: SerialPortFilter[]; // Optional port filters
349
- }
350
- ```
351
-
352
- **Options:**
353
-
354
- - `baudRate` (optional): Communication speed in bits per second. Default: `9600`
355
- - `dataBits` (optional): Number of data bits per character. Either `7` or `8`. Default: `8`
356
- - `stopBits` (optional): Number of stop bits. Either `1` or `2`. Default: `1`
357
- - `parity` (optional): Parity checking mode. `'none'`, `'even'`, or `'odd'`. Default: `'none'`
358
- - `bufferSize` (optional): Size of the read buffer. Default: `255`
359
- - `flowControl` (optional): Flow control mode. `'none'` or `'hardware'`. Default: `'none'`
360
- - `filters` (optional): Array of `SerialPortFilter` objects to filter available ports
361
-
362
- ### Error Handling
363
-
364
- #### `SerialError` Class
365
-
366
- Custom error class for serial port operations.
367
-
368
- ```typescript
369
- class SerialError extends Error {
370
- readonly code: SerialErrorCode;
371
- readonly originalError?: Error;
372
-
373
- is(code: SerialErrorCode): boolean;
374
- }
375
- ```
376
-
377
- **Properties:**
378
-
379
- - `code`: `SerialErrorCode` - The error code
380
- - `originalError?`: `Error` - The original error that caused this error (if any)
381
-
382
- **Methods:**
383
-
384
- - `is(code: SerialErrorCode): boolean` - Check if the error matches a specific error code
385
-
386
- #### `SerialErrorCode` Enum
387
-
388
- Error codes for different types of serial port errors:
389
-
390
- - `BROWSER_NOT_SUPPORTED` - Browser does not support Web Serial API
391
- - `PORT_NOT_AVAILABLE` - Serial port is not available
392
- - `PORT_OPEN_FAILED` - Failed to open serial port
393
- - `PORT_ALREADY_OPEN` - Serial port is already open
394
- - `PORT_NOT_OPEN` - Serial port is not open
395
- - `READ_FAILED` - Failed to read from serial port
396
- - `WRITE_FAILED` - Failed to write to serial port
397
- - `CONNECTION_LOST` - Serial port connection lost
398
- - `INVALID_FILTER_OPTIONS` - Invalid filter options
399
- - `OPERATION_CANCELLED` - Operation was cancelled
400
- - `UNKNOWN` - Unknown error
401
-
402
- ### Browser Detection Utilities
403
-
404
- #### `isBrowserSupported(): boolean`
405
-
406
- Checks if the browser supports the Web Serial API (non-throwing version).
407
-
408
- **Returns:** `boolean` - `true` if supported, `false` otherwise
409
-
410
- #### `checkBrowserSupport(): void`
411
-
412
- Checks if the browser supports the Web Serial API. Throws a `SerialError` if not supported.
413
-
414
- **Throws:** `SerialError` with code `BROWSER_NOT_SUPPORTED` if the browser doesn't support Web Serial API
415
-
416
- #### `detectBrowserType(): BrowserType`
417
-
418
- Detects the browser type from the user agent.
419
-
420
- **Returns:** `BrowserType` - One of `CHROME`, `EDGE`, `OPERA`, or `UNKNOWN`
421
-
422
- #### `hasWebSerialSupport(): boolean`
423
-
424
- Checks if the browser has Web Serial API support using feature detection.
425
-
426
- **Returns:** `boolean` - `true` if Web Serial API is available, `false` otherwise
427
-
428
- ### I/O Utilities
429
-
430
- #### `readableToObservable(stream: ReadableStream<Uint8Array>): Observable<Uint8Array>`
431
-
432
- Converts a `ReadableStream` to an RxJS `Observable`.
433
-
434
- **Parameters:**
435
-
436
- - `stream`: `ReadableStream<Uint8Array>` - The stream to convert
437
-
438
- **Returns:** `Observable<Uint8Array>` - Observable that emits data chunks
439
-
440
- #### `observableToWritable(observable: Observable<Uint8Array>): WritableStream<Uint8Array>`
441
-
442
- Converts an RxJS `Observable` to a `WritableStream`.
443
-
444
- **Parameters:**
445
-
446
- - `observable`: `Observable<Uint8Array>` - The observable to convert
447
-
448
- **Returns:** `WritableStream<Uint8Array>` - Writable stream that writes data from the observable
449
-
450
- #### `subscribeToWritable(observable: Observable<Uint8Array>, stream: WritableStream<Uint8Array>): { unsubscribe: () => void }`
451
-
452
- Subscribes to an Observable and writes its values to a WritableStream.
453
-
454
- **Parameters:**
455
-
456
- - `observable`: `Observable<Uint8Array>` - The observable to subscribe to
457
- - `stream`: `WritableStream<Uint8Array>` - The stream to write to
458
-
459
- **Returns:** Subscription object with `unsubscribe()` method
58
+ - **[Quick Start](docs/QUICK_START.md)** - Get started with basic examples and usage patterns
59
+ - **[API Reference](docs/API_REFERENCE.md)** - Complete API documentation with detailed descriptions
60
+ - **[Advanced Usage](docs/ADVANCED_USAGE.md)** - Advanced patterns, stream processing, and error recovery
460
61
 
461
62
  ## Framework Examples
462
63
 
@@ -471,111 +72,6 @@ This repository includes example applications demonstrating how to use web-seria
471
72
 
472
73
  Each example includes a README with setup and usage instructions.
473
74
 
474
- ## Advanced Usage
475
-
476
- ### Observable Patterns
477
-
478
- You can use RxJS operators to process serial data:
479
-
480
- ```typescript
481
- import { map, filter, bufferTime } from 'rxjs/operators';
482
-
483
- client
484
- .getReadStream()
485
- .pipe(
486
- map((data: Uint8Array) => {
487
- const decoder = new TextDecoder('utf-8');
488
- return decoder.decode(data);
489
- }),
490
- filter((text) => text.trim().length > 0),
491
- bufferTime(1000), // Buffer messages for 1 second
492
- )
493
- .subscribe({
494
- next: (messages) => {
495
- console.log('Buffered messages:', messages);
496
- },
497
- });
498
- ```
499
-
500
- ### Stream Processing
501
-
502
- Process data streams with RxJS operators:
503
-
504
- ```typescript
505
- import { map, scan, debounceTime } from 'rxjs/operators';
506
-
507
- // Accumulate received data
508
- client
509
- .getReadStream()
510
- .pipe(
511
- map((data: Uint8Array) => {
512
- const decoder = new TextDecoder('utf-8');
513
- return decoder.decode(data);
514
- }),
515
- scan((acc, current) => acc + current, ''),
516
- debounceTime(500),
517
- )
518
- .subscribe({
519
- next: (accumulated) => {
520
- console.log('Accumulated data:', accumulated);
521
- },
522
- });
523
- ```
524
-
525
- ### Custom Filters
526
-
527
- Use port filters to limit available ports:
528
-
529
- ```typescript
530
- const client = createSerialClient({
531
- baudRate: 9600,
532
- filters: [
533
- { usbVendorId: 0x1234, usbProductId: 0x5678 },
534
- { usbVendorId: 0xabcd },
535
- ],
536
- });
537
- ```
538
-
539
- ### Error Recovery
540
-
541
- Implement error recovery patterns:
542
-
543
- ```typescript
544
- import { retry, catchError } from 'rxjs/operators';
545
- import { of } from 'rxjs';
546
-
547
- client
548
- .getReadStream()
549
- .pipe(
550
- retry({
551
- count: 3,
552
- delay: 1000,
553
- }),
554
- catchError((error) => {
555
- console.error('Failed after retries:', error);
556
- return of(null); // Return empty observable
557
- }),
558
- )
559
- .subscribe({
560
- next: (data) => {
561
- if (data) {
562
- console.log('Received:', data);
563
- }
564
- },
565
- });
566
- ```
567
-
568
- ## Development and Release Strategy
569
-
570
- This project follows a **trunk-based development** approach:
571
-
572
- - **`main` branch**: Always in a release-ready state
573
- - **Short-lived branches**: `feature/*`, `fix/*`, `docs/*` for pull requests
574
- - **Releases**: Managed via Git tags (e.g., `v1.0.0`), not branches
575
- - **Version maintenance**: `release/v*` branches are added only when needed for maintaining multiple major versions
576
-
577
- For detailed contribution guidelines, see [CONTRIBUTING.md](https://github.com/gurezo/web-serial-rxjs/blob/main/CONTRIBUTING.md).
578
-
579
75
  ## Contributing
580
76
 
581
77
  We welcome contributions! Please see our [Contributing Guide](https://github.com/gurezo/web-serial-rxjs/blob/main/CONTRIBUTING.md) for details on:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gurezo/web-serial-rxjs",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "A TypeScript library that provides a reactive RxJS-based wrapper for the Web Serial API, enabling easy serial port communication in web applications.",
5
5
  "author": "Akihiko Kigure <akihiko.kigure@gmail.com>",
6
6
  "license": "MIT",
@@ -39,7 +39,7 @@
39
39
  "bugs": {
40
40
  "url": "https://github.com/gurezo/web-serial-rxjs/issues"
41
41
  },
42
- "homepage": "https://github.com/gurezo/web-serial-rxjs",
42
+ "homepage": "https://gurezo.github.io/web-serial-rxjs/",
43
43
  "keywords": [
44
44
  "rxjs",
45
45
  "serial",