@gurezo/web-serial-rxjs 3.1.0 → 4.0.0
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.
- package/README.ja.md +4 -7
- package/README.md +4 -7
- package/dist/errors/serial-error-code.d.ts +0 -21
- package/dist/errors/serial-error-code.d.ts.map +1 -1
- package/dist/errors/serial-error-context.d.ts +1 -6
- package/dist/errors/serial-error-context.d.ts.map +1 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +221 -427
- package/dist/index.mjs.map +4 -4
- package/dist/internal/branded-numbers.d.ts +1 -8
- package/dist/internal/branded-numbers.d.ts.map +1 -1
- package/dist/session/create-serial-session.d.ts +6 -4
- package/dist/session/create-serial-session.d.ts.map +1 -1
- package/dist/session/index.d.ts +2 -2
- package/dist/session/index.d.ts.map +1 -1
- package/dist/session/internal/error-severity.d.ts +0 -1
- package/dist/session/internal/error-severity.d.ts.map +1 -1
- package/dist/session/internal/has-web-serial-support.d.ts +6 -5
- package/dist/session/internal/has-web-serial-support.d.ts.map +1 -1
- package/dist/session/internal/line-buffer.d.ts +17 -0
- package/dist/session/internal/line-buffer.d.ts.map +1 -1
- package/dist/session/internal/port-teardown.d.ts +30 -0
- package/dist/session/internal/port-teardown.d.ts.map +1 -0
- package/dist/session/internal/receive-pipeline.d.ts +8 -5
- package/dist/session/internal/receive-pipeline.d.ts.map +1 -1
- package/dist/session/internal/session-error-reporter.d.ts +0 -1
- package/dist/session/internal/session-error-reporter.d.ts.map +1 -1
- package/dist/session/internal/session-lifecycle.d.ts +3 -5
- package/dist/session/internal/session-lifecycle.d.ts.map +1 -1
- package/dist/session/serial-session-options.d.ts +62 -94
- package/dist/session/serial-session-options.d.ts.map +1 -1
- package/dist/session/serial-session.d.ts +9 -75
- package/dist/session/serial-session.d.ts.map +1 -1
- package/dist/session/session-runtime.d.ts.map +1 -1
- package/dist/terminal/create-terminal-buffer.d.ts +24 -1
- package/dist/terminal/create-terminal-buffer.d.ts.map +1 -1
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/session/internal/receive-replay-buffer.d.ts +0 -38
- package/dist/session/internal/receive-replay-buffer.d.ts.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -4,13 +4,7 @@ function assertNever(value) {
|
|
|
4
4
|
}
|
|
5
5
|
|
|
6
6
|
// src/session/create-serial-session.ts
|
|
7
|
-
import {
|
|
8
|
-
BehaviorSubject as BehaviorSubject3,
|
|
9
|
-
distinctUntilChanged,
|
|
10
|
-
map as map2,
|
|
11
|
-
Observable as Observable5,
|
|
12
|
-
Subject as Subject3
|
|
13
|
-
} from "rxjs";
|
|
7
|
+
import { Observable as Observable4, Subject as Subject2 } from "rxjs";
|
|
14
8
|
|
|
15
9
|
// src/errors/serial-error-code.ts
|
|
16
10
|
var SerialErrorCode = {
|
|
@@ -134,16 +128,6 @@ var SerialErrorCode = {
|
|
|
134
128
|
* or ensure the device sends line terminators.
|
|
135
129
|
*/
|
|
136
130
|
LINE_BUFFER_OVERFLOW: "LINE_BUFFER_OVERFLOW",
|
|
137
|
-
/**
|
|
138
|
-
* Invalid receive replay options provided.
|
|
139
|
-
*
|
|
140
|
-
* This error occurs when {@link SerialSessionOptions.receiveReplay} values are
|
|
141
|
-
* out of range, such as a non-integer `bufferSize` or `maxChars`.
|
|
142
|
-
*
|
|
143
|
-
* **Suggested action**: Verify `receiveReplay` options match the documented
|
|
144
|
-
* ranges and value types.
|
|
145
|
-
*/
|
|
146
|
-
INVALID_RECEIVE_REPLAY_OPTIONS: "INVALID_RECEIVE_REPLAY_OPTIONS",
|
|
147
131
|
/**
|
|
148
132
|
* Invalid terminal buffer options provided.
|
|
149
133
|
*
|
|
@@ -174,17 +158,6 @@ var SerialErrorCode = {
|
|
|
174
158
|
* ranges and value types.
|
|
175
159
|
*/
|
|
176
160
|
INVALID_CONNECTION_OPTIONS: "INVALID_CONNECTION_OPTIONS",
|
|
177
|
-
/**
|
|
178
|
-
* Receive replay buffer exceeded its configured character limit.
|
|
179
|
-
*
|
|
180
|
-
* This error occurs when buffered chunks on {@link SerialSession.receiveReplay$}
|
|
181
|
-
* exceed {@link SerialSessionOptions.receiveReplay} `maxChars`. Oldest chunks
|
|
182
|
-
* are discarded to bound memory; the session remains connected.
|
|
183
|
-
*
|
|
184
|
-
* **Suggested action**: Increase `receiveReplay.maxChars`, reduce chunk size at
|
|
185
|
-
* the source, or subscribe earlier to avoid relying on a large replay buffer.
|
|
186
|
-
*/
|
|
187
|
-
RECEIVE_REPLAY_BUFFER_OVERFLOW: "RECEIVE_REPLAY_BUFFER_OVERFLOW",
|
|
188
161
|
/**
|
|
189
162
|
* Session has been disposed and can no longer be used.
|
|
190
163
|
*
|
|
@@ -211,6 +184,83 @@ var SerialErrorCode = {
|
|
|
211
184
|
// src/terminal/create-terminal-buffer.ts
|
|
212
185
|
import { map, scan, shareReplay } from "rxjs";
|
|
213
186
|
|
|
187
|
+
// src/errors/serial-error-context.ts
|
|
188
|
+
var CAUSE_CONTEXT_CODES = /* @__PURE__ */ new Set([
|
|
189
|
+
SerialErrorCode.PORT_NOT_AVAILABLE,
|
|
190
|
+
SerialErrorCode.PORT_OPEN_FAILED,
|
|
191
|
+
SerialErrorCode.READ_FAILED,
|
|
192
|
+
SerialErrorCode.WRITE_FAILED,
|
|
193
|
+
SerialErrorCode.CONNECTION_LOST,
|
|
194
|
+
SerialErrorCode.OPERATION_CANCELLED,
|
|
195
|
+
SerialErrorCode.UNKNOWN
|
|
196
|
+
]);
|
|
197
|
+
function isCauseContextCode(code) {
|
|
198
|
+
return CAUSE_CONTEXT_CODES.has(code);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// src/errors/serial-error.ts
|
|
202
|
+
var ErrorWithCaptureStackTrace = Error;
|
|
203
|
+
var SerialError = class _SerialError extends Error {
|
|
204
|
+
/**
|
|
205
|
+
* Creates a new SerialError instance.
|
|
206
|
+
*
|
|
207
|
+
* @param code - The error code identifying the type of error
|
|
208
|
+
* @param message - A human-readable error message
|
|
209
|
+
* @param originalError - The original error that caused this SerialError, if any.
|
|
210
|
+
* @deprecated Prefer passing `{ cause }` via {@link context}. When omitted,
|
|
211
|
+
* cause-bearing codes derive `{ cause }` from this argument for backward
|
|
212
|
+
* compatibility.
|
|
213
|
+
* @param context - Structured metadata for the error code. For cause-bearing
|
|
214
|
+
* codes, pass `{ cause }` here. When omitted, cause-bearing codes derive
|
|
215
|
+
* `{ cause }` from the legacy {@link originalError} argument.
|
|
216
|
+
*/
|
|
217
|
+
constructor(code, message, originalError, context) {
|
|
218
|
+
super(message);
|
|
219
|
+
this.name = "SerialError";
|
|
220
|
+
this.code = code;
|
|
221
|
+
if (context !== void 0) {
|
|
222
|
+
this.context = context;
|
|
223
|
+
} else if (originalError !== void 0 && isCauseContextCode(code)) {
|
|
224
|
+
this.context = { cause: originalError };
|
|
225
|
+
} else {
|
|
226
|
+
this.context = void 0;
|
|
227
|
+
}
|
|
228
|
+
if (originalError !== void 0) {
|
|
229
|
+
this.originalError = originalError;
|
|
230
|
+
} else if (isCauseContextCode(code) && this.context !== void 0) {
|
|
231
|
+
const causeContext = this.context;
|
|
232
|
+
if (causeContext.cause instanceof Error) {
|
|
233
|
+
this.originalError = causeContext.cause;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (ErrorWithCaptureStackTrace.captureStackTrace) {
|
|
237
|
+
ErrorWithCaptureStackTrace.captureStackTrace(this, _SerialError);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Check if the error matches a specific error code.
|
|
242
|
+
*
|
|
243
|
+
* This is a convenience method for checking the error code without directly
|
|
244
|
+
* comparing the code property. When this method returns `true`, TypeScript
|
|
245
|
+
* narrows `this.code` and `this.context` to the shapes defined for the
|
|
246
|
+
* provided `code` argument.
|
|
247
|
+
*
|
|
248
|
+
* @param code - The error code to check against
|
|
249
|
+
* @returns Type predicate: `true` if this error's code matches the provided
|
|
250
|
+
* code (and `this.code` / `this.context` are narrowed), `false` otherwise
|
|
251
|
+
*
|
|
252
|
+
* @example
|
|
253
|
+
* ```typescript
|
|
254
|
+
* if (error.is(SerialErrorCode.LINE_BUFFER_OVERFLOW)) {
|
|
255
|
+
* // error.code and error.context.maxChars are narrowed
|
|
256
|
+
* }
|
|
257
|
+
* ```
|
|
258
|
+
*/
|
|
259
|
+
is(code) {
|
|
260
|
+
return this.code === code;
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
|
|
214
264
|
// src/internal/branded-numbers.ts
|
|
215
265
|
function brandBaudRate(value) {
|
|
216
266
|
return value;
|
|
@@ -218,9 +268,6 @@ function brandBaudRate(value) {
|
|
|
218
268
|
function brandSerialPortBufferSize(value) {
|
|
219
269
|
return value;
|
|
220
270
|
}
|
|
221
|
-
function brandReceiveReplayBufferSize(value) {
|
|
222
|
-
return value;
|
|
223
|
-
}
|
|
224
271
|
function brandMaxChars(value) {
|
|
225
272
|
return value;
|
|
226
273
|
}
|
|
@@ -468,12 +515,40 @@ var DEFAULT_TERMINAL_BUFFER_OPTIONS = {
|
|
|
468
515
|
maxChars: 1048576,
|
|
469
516
|
stripAnsi: true
|
|
470
517
|
};
|
|
471
|
-
function
|
|
472
|
-
const
|
|
473
|
-
|
|
518
|
+
function resolveTerminalBufferOptions(options) {
|
|
519
|
+
const merged = {
|
|
520
|
+
...DEFAULT_TERMINAL_BUFFER_OPTIONS,
|
|
521
|
+
...options
|
|
522
|
+
};
|
|
523
|
+
const { maxLines, maxChars } = merged;
|
|
524
|
+
if (!Number.isSafeInteger(maxLines) || maxLines < 0) {
|
|
525
|
+
throw new SerialError(
|
|
526
|
+
SerialErrorCode.INVALID_TERMINAL_BUFFER_OPTIONS,
|
|
527
|
+
`Invalid terminalBuffer.maxLines: ${maxLines}. Must be a safe integer >= 0.`,
|
|
528
|
+
void 0,
|
|
529
|
+
{
|
|
530
|
+
field: "terminalBuffer.maxLines",
|
|
531
|
+
value: maxLines,
|
|
532
|
+
constraint: "non-negative-safe-integer"
|
|
533
|
+
}
|
|
534
|
+
);
|
|
535
|
+
}
|
|
536
|
+
if (!Number.isSafeInteger(maxChars) || maxChars < 0) {
|
|
537
|
+
throw new SerialError(
|
|
538
|
+
SerialErrorCode.INVALID_TERMINAL_BUFFER_OPTIONS,
|
|
539
|
+
`Invalid terminalBuffer.maxChars: ${maxChars}. Must be a safe integer >= 0.`,
|
|
540
|
+
void 0,
|
|
541
|
+
{
|
|
542
|
+
field: "terminalBuffer.maxChars",
|
|
543
|
+
value: maxChars,
|
|
544
|
+
constraint: "non-negative-safe-integer"
|
|
545
|
+
}
|
|
546
|
+
);
|
|
547
|
+
}
|
|
474
548
|
return {
|
|
475
549
|
maxLines: brandMaxLines(maxLines),
|
|
476
|
-
maxChars: brandMaxChars(maxChars)
|
|
550
|
+
maxChars: brandMaxChars(maxChars),
|
|
551
|
+
stripAnsi: merged.stripAnsi
|
|
477
552
|
};
|
|
478
553
|
}
|
|
479
554
|
var initialTerminalState = {
|
|
@@ -481,9 +556,12 @@ var initialTerminalState = {
|
|
|
481
556
|
currentLine: ""
|
|
482
557
|
};
|
|
483
558
|
function createTerminalBuffer(receive$, options) {
|
|
484
|
-
const
|
|
485
|
-
const
|
|
486
|
-
|
|
559
|
+
const resolved = resolveTerminalBufferOptions(options);
|
|
560
|
+
const limits = {
|
|
561
|
+
maxLines: resolved.maxLines,
|
|
562
|
+
maxChars: resolved.maxChars
|
|
563
|
+
};
|
|
564
|
+
const ansiStripper = resolved.stripAnsi ? createAnsiStripper() : null;
|
|
487
565
|
const text$ = receive$.pipe(
|
|
488
566
|
scan((state, chunk) => {
|
|
489
567
|
const normalized = ansiStripper !== null ? ansiStripper.feed(chunk) : chunk;
|
|
@@ -497,105 +575,62 @@ function createTerminalBuffer(receive$, options) {
|
|
|
497
575
|
}
|
|
498
576
|
|
|
499
577
|
// src/session/internal/has-web-serial-support.ts
|
|
500
|
-
function
|
|
578
|
+
function isWebSerialSupported() {
|
|
501
579
|
return typeof navigator !== "undefined" && "serial" in navigator && navigator.serial !== void 0 && navigator.serial !== null;
|
|
502
580
|
}
|
|
503
581
|
|
|
504
|
-
// src/session/internal/
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
// src/errors/serial-error-context.ts
|
|
513
|
-
var CAUSE_CONTEXT_CODES = /* @__PURE__ */ new Set([
|
|
514
|
-
SerialErrorCode.PORT_NOT_AVAILABLE,
|
|
515
|
-
SerialErrorCode.PORT_OPEN_FAILED,
|
|
516
|
-
SerialErrorCode.READ_FAILED,
|
|
517
|
-
SerialErrorCode.WRITE_FAILED,
|
|
518
|
-
SerialErrorCode.CONNECTION_LOST,
|
|
519
|
-
SerialErrorCode.OPERATION_CANCELLED,
|
|
520
|
-
SerialErrorCode.UNKNOWN
|
|
521
|
-
]);
|
|
522
|
-
function isCauseContextCode(code) {
|
|
523
|
-
return CAUSE_CONTEXT_CODES.has(code);
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
// src/errors/serial-error.ts
|
|
527
|
-
var ErrorWithCaptureStackTrace = Error;
|
|
528
|
-
var SerialError = class _SerialError extends Error {
|
|
529
|
-
/**
|
|
530
|
-
* Creates a new SerialError instance.
|
|
531
|
-
*
|
|
532
|
-
* @param code - The error code identifying the type of error
|
|
533
|
-
* @param message - A human-readable error message
|
|
534
|
-
* @param originalError - The original error that caused this SerialError, if any.
|
|
535
|
-
* @deprecated Prefer passing `{ cause }` via {@link context}. When omitted,
|
|
536
|
-
* cause-bearing codes derive `{ cause }` from this argument for backward
|
|
537
|
-
* compatibility.
|
|
538
|
-
* @param context - Structured metadata for the error code. For cause-bearing
|
|
539
|
-
* codes, pass `{ cause }` here. When omitted, cause-bearing codes derive
|
|
540
|
-
* `{ cause }` from the legacy {@link originalError} argument.
|
|
541
|
-
*/
|
|
542
|
-
constructor(code, message, originalError, context) {
|
|
543
|
-
super(message);
|
|
544
|
-
this.name = "SerialError";
|
|
545
|
-
this.code = code;
|
|
546
|
-
if (context !== void 0) {
|
|
547
|
-
this.context = context;
|
|
548
|
-
} else if (originalError !== void 0 && isCauseContextCode(code)) {
|
|
549
|
-
this.context = { cause: originalError };
|
|
550
|
-
} else {
|
|
551
|
-
this.context = void 0;
|
|
582
|
+
// src/session/internal/port-teardown.ts
|
|
583
|
+
function createPortTeardown(deps) {
|
|
584
|
+
const { receivePipeline } = deps;
|
|
585
|
+
const teardownPump = async (pump) => {
|
|
586
|
+
receivePipeline.clearLineBuffer();
|
|
587
|
+
if (pump) {
|
|
588
|
+
await pump.stop();
|
|
552
589
|
}
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
if (causeContext.cause instanceof Error) {
|
|
558
|
-
this.originalError = causeContext.cause;
|
|
559
|
-
}
|
|
590
|
+
};
|
|
591
|
+
const closePortSafely = async (port) => {
|
|
592
|
+
if (!port) {
|
|
593
|
+
return;
|
|
560
594
|
}
|
|
561
|
-
|
|
562
|
-
|
|
595
|
+
try {
|
|
596
|
+
await port.close();
|
|
597
|
+
} catch {
|
|
563
598
|
}
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
* narrows `this.code` and `this.context` to the shapes defined for the
|
|
571
|
-
* provided `code` argument.
|
|
572
|
-
*
|
|
573
|
-
* @param code - The error code to check against
|
|
574
|
-
* @returns Type predicate: `true` if this error's code matches the provided
|
|
575
|
-
* code (and `this.code` / `this.context` are narrowed), `false` otherwise
|
|
576
|
-
*
|
|
577
|
-
* @example
|
|
578
|
-
* ```typescript
|
|
579
|
-
* if (error.is(SerialErrorCode.LINE_BUFFER_OVERFLOW)) {
|
|
580
|
-
* // error.code and error.context.maxChars are narrowed
|
|
581
|
-
* }
|
|
582
|
-
* ```
|
|
583
|
-
*/
|
|
584
|
-
is(code) {
|
|
585
|
-
return this.code === code;
|
|
586
|
-
}
|
|
587
|
-
};
|
|
599
|
+
};
|
|
600
|
+
return { teardownPump, closePortSafely };
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// src/session/internal/receive-pipeline.ts
|
|
604
|
+
import { Subject } from "rxjs";
|
|
588
605
|
|
|
589
606
|
// src/session/internal/line-buffer.ts
|
|
590
607
|
var DEFAULT_LINE_BUFFER_OPTIONS = {
|
|
591
608
|
maxChars: 1048576
|
|
592
609
|
};
|
|
593
|
-
function
|
|
594
|
-
const
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
)
|
|
610
|
+
function resolveLineBufferOptions(options) {
|
|
611
|
+
const merged = {
|
|
612
|
+
...DEFAULT_LINE_BUFFER_OPTIONS,
|
|
613
|
+
...options
|
|
598
614
|
};
|
|
615
|
+
const { maxChars } = merged;
|
|
616
|
+
if (!Number.isSafeInteger(maxChars) || maxChars < 0) {
|
|
617
|
+
throw new SerialError(
|
|
618
|
+
SerialErrorCode.INVALID_LINE_BUFFER_OPTIONS,
|
|
619
|
+
`Invalid lineBuffer.maxChars: ${maxChars}. Must be a safe integer >= 0.`,
|
|
620
|
+
void 0,
|
|
621
|
+
{
|
|
622
|
+
field: "lineBuffer.maxChars",
|
|
623
|
+
value: maxChars,
|
|
624
|
+
constraint: "non-negative-safe-integer"
|
|
625
|
+
}
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
return {
|
|
629
|
+
maxChars: brandMaxChars(maxChars)
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
function createLineBuffer(options) {
|
|
633
|
+
const limits = resolveLineBufferOptions(options);
|
|
599
634
|
const tokenizer = createNewlineTokenizer("line");
|
|
600
635
|
const clear = () => {
|
|
601
636
|
tokenizer.clear();
|
|
@@ -614,129 +649,30 @@ function createLineBuffer(options) {
|
|
|
614
649
|
return { feed, clear };
|
|
615
650
|
}
|
|
616
651
|
|
|
617
|
-
// src/session/internal/receive-replay-buffer.ts
|
|
618
|
-
import { Observable, Subject } from "rxjs";
|
|
619
|
-
function totalChars(chunks) {
|
|
620
|
-
return chunks.reduce((sum, chunk) => sum + chunk.length, 0);
|
|
621
|
-
}
|
|
622
|
-
function createReceiveReplayBuffer(options) {
|
|
623
|
-
const chunks = [];
|
|
624
|
-
const live$ = new Subject();
|
|
625
|
-
let completed = false;
|
|
626
|
-
const trim = () => {
|
|
627
|
-
let overflowed = false;
|
|
628
|
-
while (chunks.length > options.bufferSize) {
|
|
629
|
-
chunks.shift();
|
|
630
|
-
overflowed = true;
|
|
631
|
-
}
|
|
632
|
-
if (options.maxChars > 0) {
|
|
633
|
-
let chars = totalChars(chunks);
|
|
634
|
-
while (chars > options.maxChars && chunks.length > 1) {
|
|
635
|
-
chars -= chunks.shift().length;
|
|
636
|
-
overflowed = true;
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
return overflowed;
|
|
640
|
-
};
|
|
641
|
-
const next = (chunk) => {
|
|
642
|
-
if (completed) {
|
|
643
|
-
return { overflowed: false };
|
|
644
|
-
}
|
|
645
|
-
chunks.push(chunk);
|
|
646
|
-
const overflowed = trim();
|
|
647
|
-
live$.next(chunk);
|
|
648
|
-
return { overflowed };
|
|
649
|
-
};
|
|
650
|
-
const asObservable = () => new Observable((subscriber) => {
|
|
651
|
-
for (const chunk of chunks) {
|
|
652
|
-
subscriber.next(chunk);
|
|
653
|
-
}
|
|
654
|
-
if (completed) {
|
|
655
|
-
subscriber.complete();
|
|
656
|
-
return;
|
|
657
|
-
}
|
|
658
|
-
return live$.subscribe(subscriber);
|
|
659
|
-
});
|
|
660
|
-
const complete = () => {
|
|
661
|
-
if (completed) {
|
|
662
|
-
return;
|
|
663
|
-
}
|
|
664
|
-
completed = true;
|
|
665
|
-
chunks.length = 0;
|
|
666
|
-
live$.complete();
|
|
667
|
-
};
|
|
668
|
-
return { next, asObservable, complete };
|
|
669
|
-
}
|
|
670
|
-
|
|
671
652
|
// src/session/internal/receive-pipeline.ts
|
|
672
653
|
function createReceivePipeline(deps) {
|
|
673
|
-
const { resolvedOptions
|
|
674
|
-
const receiveSubject = new
|
|
675
|
-
const linesSubject = new
|
|
654
|
+
const { resolvedOptions } = deps;
|
|
655
|
+
const receiveSubject = new Subject();
|
|
656
|
+
const linesSubject = new Subject();
|
|
657
|
+
const bufferErrorsSubject = new Subject();
|
|
676
658
|
const lineBuffer = createLineBuffer(resolvedOptions.lineBuffer);
|
|
677
659
|
const receive$ = receiveSubject.asObservable();
|
|
678
660
|
const lines$ = linesSubject.asObservable();
|
|
679
|
-
const
|
|
680
|
-
let activeReceiveReplay = null;
|
|
681
|
-
const clearReplay = () => {
|
|
682
|
-
if (receiveReplayStream$) {
|
|
683
|
-
if (activeReceiveReplay) {
|
|
684
|
-
activeReceiveReplay.complete();
|
|
685
|
-
activeReceiveReplay = null;
|
|
686
|
-
}
|
|
687
|
-
receiveReplayStream$.next(receive$);
|
|
688
|
-
}
|
|
689
|
-
};
|
|
690
|
-
const startLiveReceiveReplay = () => {
|
|
691
|
-
if (!receiveReplayStream$) {
|
|
692
|
-
return;
|
|
693
|
-
}
|
|
694
|
-
if (activeReceiveReplay) {
|
|
695
|
-
activeReceiveReplay.complete();
|
|
696
|
-
activeReceiveReplay = null;
|
|
697
|
-
}
|
|
698
|
-
const buffer = createReceiveReplayBuffer({
|
|
699
|
-
bufferSize: resolvedOptions.receiveReplay.bufferSize,
|
|
700
|
-
maxChars: resolvedOptions.receiveReplay.maxChars
|
|
701
|
-
});
|
|
702
|
-
activeReceiveReplay = buffer;
|
|
703
|
-
receiveReplayStream$.next(buffer.asObservable());
|
|
704
|
-
};
|
|
705
|
-
const receiveReplay$ = receiveReplayStream$ ? receiveReplayStream$.pipe(switchMap((inner) => inner), share()) : receive$;
|
|
661
|
+
const bufferErrors$ = bufferErrorsSubject.asObservable();
|
|
706
662
|
const clearLineBuffer = () => {
|
|
707
663
|
lineBuffer.clear();
|
|
708
664
|
};
|
|
709
665
|
const handleChunk = (text) => {
|
|
710
666
|
receiveSubject.next(text);
|
|
711
|
-
if (activeReceiveReplay) {
|
|
712
|
-
const { overflowed: overflowed2 } = activeReceiveReplay.next(text);
|
|
713
|
-
if (overflowed2) {
|
|
714
|
-
reportError(
|
|
715
|
-
new SerialError(
|
|
716
|
-
SerialErrorCode.RECEIVE_REPLAY_BUFFER_OVERFLOW,
|
|
717
|
-
"Receive replay buffer exceeded configured limits; oldest chunks were discarded",
|
|
718
|
-
void 0,
|
|
719
|
-
{
|
|
720
|
-
maxChars: resolvedOptions.receiveReplay.maxChars,
|
|
721
|
-
bufferSize: resolvedOptions.receiveReplay.bufferSize
|
|
722
|
-
}
|
|
723
|
-
),
|
|
724
|
-
{
|
|
725
|
-
fallbackCode: SerialErrorCode.RECEIVE_REPLAY_BUFFER_OVERFLOW
|
|
726
|
-
}
|
|
727
|
-
);
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
667
|
const { lines, overflowed } = lineBuffer.feed(text);
|
|
731
668
|
if (overflowed) {
|
|
732
|
-
|
|
669
|
+
bufferErrorsSubject.next(
|
|
733
670
|
new SerialError(
|
|
734
671
|
SerialErrorCode.LINE_BUFFER_OVERFLOW,
|
|
735
672
|
"Line buffer exceeded maxChars; leading data was discarded",
|
|
736
673
|
void 0,
|
|
737
674
|
{ maxChars: resolvedOptions.lineBuffer.maxChars }
|
|
738
|
-
)
|
|
739
|
-
{ fallbackCode: SerialErrorCode.LINE_BUFFER_OVERFLOW }
|
|
675
|
+
)
|
|
740
676
|
);
|
|
741
677
|
}
|
|
742
678
|
for (const line of lines) {
|
|
@@ -746,14 +682,12 @@ function createReceivePipeline(deps) {
|
|
|
746
682
|
const complete = () => {
|
|
747
683
|
receiveSubject.complete();
|
|
748
684
|
linesSubject.complete();
|
|
749
|
-
|
|
685
|
+
bufferErrorsSubject.complete();
|
|
750
686
|
};
|
|
751
687
|
return {
|
|
752
688
|
receive$,
|
|
753
689
|
lines$,
|
|
754
|
-
|
|
755
|
-
clearReplay,
|
|
756
|
-
startLiveReceiveReplay,
|
|
690
|
+
bufferErrors$,
|
|
757
691
|
clearLineBuffer,
|
|
758
692
|
handleChunk,
|
|
759
693
|
complete
|
|
@@ -768,7 +702,6 @@ var ERROR_SEVERITY = {
|
|
|
768
702
|
[SerialErrorCode.OPERATION_CANCELLED]: "fatal",
|
|
769
703
|
[SerialErrorCode.UNKNOWN]: "fatal",
|
|
770
704
|
[SerialErrorCode.LINE_BUFFER_OVERFLOW]: "non-fatal",
|
|
771
|
-
[SerialErrorCode.RECEIVE_REPLAY_BUFFER_OVERFLOW]: "non-fatal",
|
|
772
705
|
[SerialErrorCode.BROWSER_NOT_SUPPORTED]: "non-fatal",
|
|
773
706
|
[SerialErrorCode.PORT_ALREADY_OPEN]: "non-fatal",
|
|
774
707
|
[SerialErrorCode.PORT_NOT_OPEN]: "non-fatal",
|
|
@@ -807,7 +740,7 @@ function normalizeSerialError(error, options) {
|
|
|
807
740
|
}
|
|
808
741
|
|
|
809
742
|
// src/session/session-runtime.ts
|
|
810
|
-
import { BehaviorSubject
|
|
743
|
+
import { BehaviorSubject } from "rxjs";
|
|
811
744
|
|
|
812
745
|
// src/session/serial-session-state.ts
|
|
813
746
|
var SerialSessionStatus = {
|
|
@@ -904,7 +837,7 @@ function getRuntimePump(runtime) {
|
|
|
904
837
|
}
|
|
905
838
|
function createSessionRuntimeController(initial) {
|
|
906
839
|
let runtime = initial;
|
|
907
|
-
const subject = new
|
|
840
|
+
const subject = new BehaviorSubject(
|
|
908
841
|
runtimeToPublicState(initial)
|
|
909
842
|
);
|
|
910
843
|
const transition = (next) => {
|
|
@@ -921,8 +854,9 @@ function createSessionRuntimeController(initial) {
|
|
|
921
854
|
}
|
|
922
855
|
return false;
|
|
923
856
|
}
|
|
857
|
+
const publicState = runtimeToPublicState(next);
|
|
924
858
|
runtime = next;
|
|
925
|
-
subject.next(
|
|
859
|
+
subject.next(publicState);
|
|
926
860
|
return true;
|
|
927
861
|
};
|
|
928
862
|
return {
|
|
@@ -952,7 +886,6 @@ function createSessionErrorReporter(deps) {
|
|
|
952
886
|
errorsSubject,
|
|
953
887
|
sendQueue,
|
|
954
888
|
isDisposed,
|
|
955
|
-
updatePortInfo,
|
|
956
889
|
teardownPump,
|
|
957
890
|
closePortSafely
|
|
958
891
|
} = deps;
|
|
@@ -972,7 +905,6 @@ function createSessionErrorReporter(deps) {
|
|
|
972
905
|
const pump = getRuntimePump(runtime);
|
|
973
906
|
controller.transition(createErrorRuntime(serialError));
|
|
974
907
|
sendQueue.clear();
|
|
975
|
-
updatePortInfo(null);
|
|
976
908
|
void teardownPump(pump).then(() => closePortSafely(portToClose));
|
|
977
909
|
}
|
|
978
910
|
return serialError;
|
|
@@ -981,7 +913,7 @@ function createSessionErrorReporter(deps) {
|
|
|
981
913
|
}
|
|
982
914
|
|
|
983
915
|
// src/session/internal/session-lifecycle.ts
|
|
984
|
-
import { Observable as
|
|
916
|
+
import { Observable as Observable2 } from "rxjs";
|
|
985
917
|
|
|
986
918
|
// src/session/internal/build-request-options.ts
|
|
987
919
|
function buildRequestOptions(options) {
|
|
@@ -1094,31 +1026,13 @@ function createSessionLifecycle(deps) {
|
|
|
1094
1026
|
resolvedOptions,
|
|
1095
1027
|
sendQueue,
|
|
1096
1028
|
receivePipeline,
|
|
1097
|
-
portInfoSubject,
|
|
1098
1029
|
errorsSubject,
|
|
1099
1030
|
isDisposed,
|
|
1031
|
+
teardownPump,
|
|
1032
|
+
closePortSafely,
|
|
1100
1033
|
reportError,
|
|
1101
1034
|
createDisposedError
|
|
1102
1035
|
} = deps;
|
|
1103
|
-
const updatePortInfo = (port) => {
|
|
1104
|
-
portInfoSubject.next(port ? port.getInfo() : null);
|
|
1105
|
-
};
|
|
1106
|
-
const teardownPump = async (pump) => {
|
|
1107
|
-
receivePipeline.clearReplay();
|
|
1108
|
-
receivePipeline.clearLineBuffer();
|
|
1109
|
-
if (pump) {
|
|
1110
|
-
await pump.stop();
|
|
1111
|
-
}
|
|
1112
|
-
};
|
|
1113
|
-
const closePortSafely = async (port) => {
|
|
1114
|
-
if (!port) {
|
|
1115
|
-
return;
|
|
1116
|
-
}
|
|
1117
|
-
try {
|
|
1118
|
-
await port.close();
|
|
1119
|
-
} catch {
|
|
1120
|
-
}
|
|
1121
|
-
};
|
|
1122
1036
|
const teardownFromSnapshot = async (snapshot) => {
|
|
1123
1037
|
if (snapshot.status === SerialSessionStatus.Connecting) {
|
|
1124
1038
|
snapshot.cancel();
|
|
@@ -1129,7 +1043,6 @@ function createSessionLifecycle(deps) {
|
|
|
1129
1043
|
const pump = getRuntimePump(snapshot);
|
|
1130
1044
|
await teardownPump(pump);
|
|
1131
1045
|
await closePortSafely(portToClose);
|
|
1132
|
-
updatePortInfo(null);
|
|
1133
1046
|
}
|
|
1134
1047
|
receivePipeline.clearLineBuffer();
|
|
1135
1048
|
};
|
|
@@ -1137,9 +1050,8 @@ function createSessionLifecycle(deps) {
|
|
|
1137
1050
|
controller.complete();
|
|
1138
1051
|
errorsSubject.complete();
|
|
1139
1052
|
receivePipeline.complete();
|
|
1140
|
-
portInfoSubject.complete();
|
|
1141
1053
|
};
|
|
1142
|
-
const dispose$ = () => new
|
|
1054
|
+
const dispose$ = () => new Observable2((subscriber) => {
|
|
1143
1055
|
if (isDisposed()) {
|
|
1144
1056
|
subscriber.next();
|
|
1145
1057
|
subscriber.complete();
|
|
@@ -1181,12 +1093,12 @@ function createSessionLifecycle(deps) {
|
|
|
1181
1093
|
}
|
|
1182
1094
|
}
|
|
1183
1095
|
};
|
|
1184
|
-
const connect$ = () => new
|
|
1096
|
+
const connect$ = () => new Observable2((subscriber) => {
|
|
1185
1097
|
if (isDisposed()) {
|
|
1186
1098
|
subscriber.error(createDisposedError());
|
|
1187
1099
|
return;
|
|
1188
1100
|
}
|
|
1189
|
-
if (!
|
|
1101
|
+
if (!isWebSerialSupported()) {
|
|
1190
1102
|
const error = reportError(
|
|
1191
1103
|
new SerialError(
|
|
1192
1104
|
SerialErrorCode.BROWSER_NOT_SUPPORTED,
|
|
@@ -1249,9 +1161,6 @@ function createSessionLifecycle(deps) {
|
|
|
1249
1161
|
return;
|
|
1250
1162
|
}
|
|
1251
1163
|
receivePipeline.clearLineBuffer();
|
|
1252
|
-
if (resolvedOptions.receiveReplay.enabled) {
|
|
1253
|
-
receivePipeline.startLiveReceiveReplay();
|
|
1254
|
-
}
|
|
1255
1164
|
const pump = createReadPump(selectedPort, {
|
|
1256
1165
|
onChunk: receivePipeline.handleChunk,
|
|
1257
1166
|
onError: (pumpError) => reportError(pumpError, {
|
|
@@ -1281,7 +1190,6 @@ function createSessionLifecycle(deps) {
|
|
|
1281
1190
|
return;
|
|
1282
1191
|
}
|
|
1283
1192
|
controller.transition(createConnectedRuntime(selectedPort, pump));
|
|
1284
|
-
updatePortInfo(selectedPort);
|
|
1285
1193
|
subscriber.next();
|
|
1286
1194
|
subscriber.complete();
|
|
1287
1195
|
};
|
|
@@ -1290,7 +1198,7 @@ function createSessionLifecycle(deps) {
|
|
|
1290
1198
|
cancelInFlightConnect();
|
|
1291
1199
|
};
|
|
1292
1200
|
});
|
|
1293
|
-
const disconnect$ = () => new
|
|
1201
|
+
const disconnect$ = () => new Observable2((subscriber) => {
|
|
1294
1202
|
if (isDisposed()) {
|
|
1295
1203
|
subscriber.next();
|
|
1296
1204
|
subscriber.complete();
|
|
@@ -1330,7 +1238,6 @@ function createSessionLifecycle(deps) {
|
|
|
1330
1238
|
try {
|
|
1331
1239
|
await portToClose.close();
|
|
1332
1240
|
} catch (error) {
|
|
1333
|
-
updatePortInfo(null);
|
|
1334
1241
|
const serialError = reportError(error, {
|
|
1335
1242
|
fallbackCode: SerialErrorCode.CONNECTION_LOST,
|
|
1336
1243
|
messagePrefix: "Failed to close port"
|
|
@@ -1339,7 +1246,6 @@ function createSessionLifecycle(deps) {
|
|
|
1339
1246
|
return;
|
|
1340
1247
|
}
|
|
1341
1248
|
}
|
|
1342
|
-
updatePortInfo(null);
|
|
1343
1249
|
if (!isDisposed()) {
|
|
1344
1250
|
controller.transition(createIdleRuntime());
|
|
1345
1251
|
}
|
|
@@ -1359,21 +1265,18 @@ function createSessionLifecycle(deps) {
|
|
|
1359
1265
|
connect$,
|
|
1360
1266
|
disconnect$,
|
|
1361
1267
|
dispose$,
|
|
1362
|
-
writeToPort
|
|
1363
|
-
teardownPump,
|
|
1364
|
-
closePortSafely,
|
|
1365
|
-
updatePortInfo
|
|
1268
|
+
writeToPort
|
|
1366
1269
|
};
|
|
1367
1270
|
}
|
|
1368
1271
|
|
|
1369
1272
|
// src/session/send-queue.ts
|
|
1370
|
-
import { Observable as
|
|
1273
|
+
import { Observable as Observable3, defer } from "rxjs";
|
|
1371
1274
|
function createSendQueue() {
|
|
1372
1275
|
let chain = Promise.resolve();
|
|
1373
1276
|
return {
|
|
1374
1277
|
enqueue(operation) {
|
|
1375
1278
|
return defer(
|
|
1376
|
-
() => new
|
|
1279
|
+
() => new Observable3((subscriber) => {
|
|
1377
1280
|
let cancelled = false;
|
|
1378
1281
|
const run = async () => {
|
|
1379
1282
|
try {
|
|
@@ -1463,107 +1366,6 @@ function validateSerialPortFilters(filters) {
|
|
|
1463
1366
|
}
|
|
1464
1367
|
|
|
1465
1368
|
// src/session/serial-session-options.ts
|
|
1466
|
-
var MAX_RECEIVE_REPLAY_BUFFER_SIZE = 65536;
|
|
1467
|
-
var MAX_RECEIVE_REPLAY_MAX_CHARS = 1048576;
|
|
1468
|
-
var DEFAULT_RECEIVE_REPLAY = {
|
|
1469
|
-
enabled: false,
|
|
1470
|
-
bufferSize: 512,
|
|
1471
|
-
maxChars: 0
|
|
1472
|
-
};
|
|
1473
|
-
function resolveReceiveReplayOptions(options) {
|
|
1474
|
-
const merged = {
|
|
1475
|
-
...DEFAULT_RECEIVE_REPLAY,
|
|
1476
|
-
...options
|
|
1477
|
-
};
|
|
1478
|
-
const { bufferSize, maxChars } = merged;
|
|
1479
|
-
if (!Number.isSafeInteger(bufferSize) || bufferSize < 1 || bufferSize > MAX_RECEIVE_REPLAY_BUFFER_SIZE) {
|
|
1480
|
-
throw new SerialError(
|
|
1481
|
-
SerialErrorCode.INVALID_RECEIVE_REPLAY_OPTIONS,
|
|
1482
|
-
`Invalid receiveReplay.bufferSize: ${bufferSize}. Must be a safe integer between 1 and ${MAX_RECEIVE_REPLAY_BUFFER_SIZE}.`,
|
|
1483
|
-
void 0,
|
|
1484
|
-
{
|
|
1485
|
-
field: "receiveReplay.bufferSize",
|
|
1486
|
-
value: bufferSize,
|
|
1487
|
-
constraint: "receive-replay-buffer-size-range"
|
|
1488
|
-
}
|
|
1489
|
-
);
|
|
1490
|
-
}
|
|
1491
|
-
if (!Number.isSafeInteger(maxChars) || maxChars < 0 || maxChars > MAX_RECEIVE_REPLAY_MAX_CHARS) {
|
|
1492
|
-
throw new SerialError(
|
|
1493
|
-
SerialErrorCode.INVALID_RECEIVE_REPLAY_OPTIONS,
|
|
1494
|
-
`Invalid receiveReplay.maxChars: ${maxChars}. Must be a safe integer between 0 and ${MAX_RECEIVE_REPLAY_MAX_CHARS}.`,
|
|
1495
|
-
void 0,
|
|
1496
|
-
{
|
|
1497
|
-
field: "receiveReplay.maxChars",
|
|
1498
|
-
value: maxChars,
|
|
1499
|
-
constraint: "receive-replay-max-chars-range"
|
|
1500
|
-
}
|
|
1501
|
-
);
|
|
1502
|
-
}
|
|
1503
|
-
return {
|
|
1504
|
-
enabled: merged.enabled,
|
|
1505
|
-
bufferSize: brandReceiveReplayBufferSize(bufferSize),
|
|
1506
|
-
maxChars: brandMaxChars(maxChars)
|
|
1507
|
-
};
|
|
1508
|
-
}
|
|
1509
|
-
function resolveTerminalBufferOptions(options) {
|
|
1510
|
-
const merged = {
|
|
1511
|
-
...DEFAULT_TERMINAL_BUFFER_OPTIONS,
|
|
1512
|
-
...options
|
|
1513
|
-
};
|
|
1514
|
-
const { maxLines, maxChars } = merged;
|
|
1515
|
-
if (!Number.isSafeInteger(maxLines) || maxLines < 0) {
|
|
1516
|
-
throw new SerialError(
|
|
1517
|
-
SerialErrorCode.INVALID_TERMINAL_BUFFER_OPTIONS,
|
|
1518
|
-
`Invalid terminalBuffer.maxLines: ${maxLines}. Must be a safe integer >= 0.`,
|
|
1519
|
-
void 0,
|
|
1520
|
-
{
|
|
1521
|
-
field: "terminalBuffer.maxLines",
|
|
1522
|
-
value: maxLines,
|
|
1523
|
-
constraint: "non-negative-safe-integer"
|
|
1524
|
-
}
|
|
1525
|
-
);
|
|
1526
|
-
}
|
|
1527
|
-
if (!Number.isSafeInteger(maxChars) || maxChars < 0) {
|
|
1528
|
-
throw new SerialError(
|
|
1529
|
-
SerialErrorCode.INVALID_TERMINAL_BUFFER_OPTIONS,
|
|
1530
|
-
`Invalid terminalBuffer.maxChars: ${maxChars}. Must be a safe integer >= 0.`,
|
|
1531
|
-
void 0,
|
|
1532
|
-
{
|
|
1533
|
-
field: "terminalBuffer.maxChars",
|
|
1534
|
-
value: maxChars,
|
|
1535
|
-
constraint: "non-negative-safe-integer"
|
|
1536
|
-
}
|
|
1537
|
-
);
|
|
1538
|
-
}
|
|
1539
|
-
return {
|
|
1540
|
-
maxLines: brandMaxLines(maxLines),
|
|
1541
|
-
maxChars: brandMaxChars(maxChars),
|
|
1542
|
-
stripAnsi: merged.stripAnsi
|
|
1543
|
-
};
|
|
1544
|
-
}
|
|
1545
|
-
function resolveLineBufferOptions(options) {
|
|
1546
|
-
const merged = {
|
|
1547
|
-
...DEFAULT_LINE_BUFFER_OPTIONS,
|
|
1548
|
-
...options
|
|
1549
|
-
};
|
|
1550
|
-
const { maxChars } = merged;
|
|
1551
|
-
if (!Number.isSafeInteger(maxChars) || maxChars < 0) {
|
|
1552
|
-
throw new SerialError(
|
|
1553
|
-
SerialErrorCode.INVALID_LINE_BUFFER_OPTIONS,
|
|
1554
|
-
`Invalid lineBuffer.maxChars: ${maxChars}. Must be a safe integer >= 0.`,
|
|
1555
|
-
void 0,
|
|
1556
|
-
{
|
|
1557
|
-
field: "lineBuffer.maxChars",
|
|
1558
|
-
value: maxChars,
|
|
1559
|
-
constraint: "non-negative-safe-integer"
|
|
1560
|
-
}
|
|
1561
|
-
);
|
|
1562
|
-
}
|
|
1563
|
-
return {
|
|
1564
|
-
maxChars: brandMaxChars(maxChars)
|
|
1565
|
-
};
|
|
1566
|
-
}
|
|
1567
1369
|
var DEFAULT_SERIAL_SESSION_OPTIONS = {
|
|
1568
1370
|
baudRate: brandBaudRate(9600),
|
|
1569
1371
|
dataBits: 8,
|
|
@@ -1571,7 +1373,6 @@ var DEFAULT_SERIAL_SESSION_OPTIONS = {
|
|
|
1571
1373
|
parity: "none",
|
|
1572
1374
|
bufferSize: brandSerialPortBufferSize(255),
|
|
1573
1375
|
flowControl: "none",
|
|
1574
|
-
receiveReplay: resolveReceiveReplayOptions(),
|
|
1575
1376
|
terminalBuffer: resolveTerminalBufferOptions(),
|
|
1576
1377
|
lineBuffer: resolveLineBufferOptions()
|
|
1577
1378
|
};
|
|
@@ -1585,7 +1386,8 @@ function resolveConnectionOptions(options) {
|
|
|
1585
1386
|
flowControl: DEFAULT_SERIAL_SESSION_OPTIONS.flowControl,
|
|
1586
1387
|
...options
|
|
1587
1388
|
};
|
|
1588
|
-
const
|
|
1389
|
+
const baudRate = merged.baudRate ?? DEFAULT_SERIAL_SESSION_OPTIONS.baudRate;
|
|
1390
|
+
const bufferSize = merged.bufferSize ?? DEFAULT_SERIAL_SESSION_OPTIONS.bufferSize;
|
|
1589
1391
|
if (!Number.isSafeInteger(baudRate) || baudRate <= 0) {
|
|
1590
1392
|
throw new SerialError(
|
|
1591
1393
|
SerialErrorCode.INVALID_CONNECTION_OPTIONS,
|
|
@@ -1598,15 +1400,25 @@ function resolveConnectionOptions(options) {
|
|
|
1598
1400
|
}
|
|
1599
1401
|
);
|
|
1600
1402
|
}
|
|
1403
|
+
if (!Number.isSafeInteger(bufferSize) || bufferSize <= 0) {
|
|
1404
|
+
throw new SerialError(
|
|
1405
|
+
SerialErrorCode.INVALID_CONNECTION_OPTIONS,
|
|
1406
|
+
`Invalid bufferSize: ${bufferSize}. Must be a safe integer > 0.`,
|
|
1407
|
+
void 0,
|
|
1408
|
+
{
|
|
1409
|
+
field: "bufferSize",
|
|
1410
|
+
value: bufferSize,
|
|
1411
|
+
constraint: "positive-safe-integer"
|
|
1412
|
+
}
|
|
1413
|
+
);
|
|
1414
|
+
}
|
|
1601
1415
|
return {
|
|
1602
1416
|
dataBits: merged.dataBits ?? DEFAULT_SERIAL_SESSION_OPTIONS.dataBits,
|
|
1603
1417
|
stopBits: merged.stopBits ?? DEFAULT_SERIAL_SESSION_OPTIONS.stopBits,
|
|
1604
1418
|
parity: merged.parity ?? DEFAULT_SERIAL_SESSION_OPTIONS.parity,
|
|
1605
1419
|
flowControl: merged.flowControl ?? DEFAULT_SERIAL_SESSION_OPTIONS.flowControl,
|
|
1606
1420
|
baudRate: brandBaudRate(baudRate),
|
|
1607
|
-
bufferSize: brandSerialPortBufferSize(
|
|
1608
|
-
bufferSize ?? DEFAULT_SERIAL_SESSION_OPTIONS.bufferSize
|
|
1609
|
-
)
|
|
1421
|
+
bufferSize: brandSerialPortBufferSize(bufferSize)
|
|
1610
1422
|
};
|
|
1611
1423
|
}
|
|
1612
1424
|
function resolveSerialSessionOptions(options) {
|
|
@@ -1615,7 +1427,6 @@ function resolveSerialSessionOptions(options) {
|
|
|
1615
1427
|
return {
|
|
1616
1428
|
...connection,
|
|
1617
1429
|
...filters !== void 0 ? { filters } : {},
|
|
1618
|
-
receiveReplay: resolveReceiveReplayOptions(options?.receiveReplay),
|
|
1619
1430
|
terminalBuffer: resolveTerminalBufferOptions(options?.terminalBuffer),
|
|
1620
1431
|
lineBuffer: resolveLineBufferOptions(options?.lineBuffer)
|
|
1621
1432
|
};
|
|
@@ -1625,62 +1436,52 @@ function resolveSerialSessionOptions(options) {
|
|
|
1625
1436
|
function createSerialSession(options) {
|
|
1626
1437
|
const resolvedOptions = resolveSerialSessionOptions(options);
|
|
1627
1438
|
const controller = createSessionRuntimeController(
|
|
1628
|
-
createInitialRuntime(
|
|
1439
|
+
createInitialRuntime(isWebSerialSupported())
|
|
1629
1440
|
);
|
|
1630
|
-
const errorsSubject = new
|
|
1441
|
+
const errorsSubject = new Subject2();
|
|
1631
1442
|
const sendQueue = createSendQueue();
|
|
1632
1443
|
const textEncoder = new TextEncoder();
|
|
1633
|
-
const portInfoSubject = new BehaviorSubject3(null);
|
|
1634
1444
|
const isDisposed = () => controller.status === SerialSessionStatus.Disposed;
|
|
1635
|
-
const
|
|
1636
|
-
const
|
|
1637
|
-
|
|
1638
|
-
reportError: (error, options2) => errorReporterRef.reportError(error, options2)
|
|
1445
|
+
const receivePipeline = createReceivePipeline({ resolvedOptions });
|
|
1446
|
+
const { teardownPump, closePortSafely } = createPortTeardown({
|
|
1447
|
+
receivePipeline
|
|
1639
1448
|
});
|
|
1640
|
-
const
|
|
1449
|
+
const { reportError, createDisposedError } = createSessionErrorReporter({
|
|
1641
1450
|
controller,
|
|
1642
|
-
resolvedOptions,
|
|
1643
|
-
sendQueue,
|
|
1644
|
-
receivePipeline,
|
|
1645
|
-
portInfoSubject,
|
|
1646
1451
|
errorsSubject,
|
|
1452
|
+
sendQueue,
|
|
1647
1453
|
isDisposed,
|
|
1648
|
-
|
|
1649
|
-
|
|
1454
|
+
teardownPump,
|
|
1455
|
+
closePortSafely
|
|
1650
1456
|
});
|
|
1651
|
-
|
|
1457
|
+
receivePipeline.bufferErrors$.subscribe(
|
|
1458
|
+
(error) => reportError(error, { fallbackCode: error.code })
|
|
1459
|
+
);
|
|
1460
|
+
const lifecycle = createSessionLifecycle({
|
|
1652
1461
|
controller,
|
|
1653
|
-
|
|
1462
|
+
resolvedOptions,
|
|
1654
1463
|
sendQueue,
|
|
1464
|
+
receivePipeline,
|
|
1465
|
+
errorsSubject,
|
|
1655
1466
|
isDisposed,
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1467
|
+
teardownPump,
|
|
1468
|
+
closePortSafely,
|
|
1469
|
+
reportError,
|
|
1470
|
+
createDisposedError
|
|
1659
1471
|
});
|
|
1660
|
-
|
|
1661
|
-
errorReporterRef.createDisposedError = createDisposedError;
|
|
1662
|
-
const { receive$, lines$, receiveReplay$ } = receivePipeline;
|
|
1472
|
+
const { receive$, lines$ } = receivePipeline;
|
|
1663
1473
|
const errors$ = errorsSubject.asObservable();
|
|
1664
1474
|
const terminalText$ = createTerminalBuffer(
|
|
1665
1475
|
receive$,
|
|
1666
1476
|
resolvedOptions.terminalBuffer
|
|
1667
1477
|
).text$;
|
|
1668
|
-
const isConnected$ = controller.state$.pipe(
|
|
1669
|
-
map2((state) => state.status === SerialSessionStatus.Connected),
|
|
1670
|
-
distinctUntilChanged()
|
|
1671
|
-
);
|
|
1672
|
-
const portInfo$ = portInfoSubject.asObservable();
|
|
1673
1478
|
return {
|
|
1674
|
-
isBrowserSupported() {
|
|
1675
|
-
return hasWebSerialSupport();
|
|
1676
|
-
},
|
|
1677
1479
|
connect$: lifecycle.connect$,
|
|
1678
1480
|
disconnect$: lifecycle.disconnect$,
|
|
1679
1481
|
dispose$: lifecycle.dispose$,
|
|
1680
|
-
destroy$: lifecycle.dispose$,
|
|
1681
1482
|
send$(data) {
|
|
1682
1483
|
if (isDisposed()) {
|
|
1683
|
-
return new
|
|
1484
|
+
return new Observable4((subscriber) => {
|
|
1684
1485
|
subscriber.error(createDisposedError());
|
|
1685
1486
|
});
|
|
1686
1487
|
}
|
|
@@ -1697,15 +1498,9 @@ function createSerialSession(options) {
|
|
|
1697
1498
|
});
|
|
1698
1499
|
},
|
|
1699
1500
|
state$: controller.state$,
|
|
1700
|
-
isConnected$,
|
|
1701
|
-
portInfo$,
|
|
1702
|
-
getPortInfo() {
|
|
1703
|
-
return portInfoSubject.getValue();
|
|
1704
|
-
},
|
|
1705
1501
|
errors$,
|
|
1706
1502
|
receive$,
|
|
1707
1503
|
terminalText$,
|
|
1708
|
-
receiveReplay$,
|
|
1709
1504
|
lines$
|
|
1710
1505
|
};
|
|
1711
1506
|
}
|
|
@@ -1717,8 +1512,6 @@ function isConnectedSessionState(state) {
|
|
|
1717
1512
|
export {
|
|
1718
1513
|
DEFAULT_LINE_BUFFER_OPTIONS,
|
|
1719
1514
|
DEFAULT_TERMINAL_BUFFER_OPTIONS,
|
|
1720
|
-
MAX_RECEIVE_REPLAY_BUFFER_SIZE,
|
|
1721
|
-
MAX_RECEIVE_REPLAY_MAX_CHARS,
|
|
1722
1515
|
SerialError,
|
|
1723
1516
|
SerialErrorCode,
|
|
1724
1517
|
SerialSessionStatus,
|
|
@@ -1726,6 +1519,7 @@ export {
|
|
|
1726
1519
|
createSerialSession,
|
|
1727
1520
|
createTerminalBuffer,
|
|
1728
1521
|
isConnectedSessionState,
|
|
1522
|
+
isWebSerialSupported,
|
|
1729
1523
|
resolveSerialSessionOptions
|
|
1730
1524
|
};
|
|
1731
1525
|
//# sourceMappingURL=index.mjs.map
|