@mcpwarp/ws-mixer 0.6.0 → 0.7.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/CHANGELOG.md +63 -0
- package/README.md +29 -5
- package/dist/client.d.ts +4 -4
- package/dist/conn.d.ts +38 -6
- package/dist/errors.d.ts +11 -1
- package/dist/index.cjs +260 -84
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +260 -84
- package/dist/index.js.map +1 -1
- package/dist/stream.d.ts +59 -7
- package/package.json +1 -1
package/dist/stream.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MixerStream: one ws-mixer byte stream, exposed as a Node Duplex.
|
|
3
|
-
* Mirrors `go/wsmixer/stream.go`'s state machine, credit accounting and
|
|
3
|
+
* Mirrors `ws-mixer-go/wsmixer/stream.go`'s state machine, credit accounting and
|
|
4
4
|
* half-close semantics (WIRE.md section 2.5-2.6). The JS SDK is always
|
|
5
5
|
* the answering peer: it never opens streams, only receives OPEN from the
|
|
6
6
|
* server and reads/writes/closes/resets what arrives.
|
|
@@ -30,8 +30,10 @@ export interface StreamHost {
|
|
|
30
30
|
sendData(streamId: number, chunk: Uint8Array): Promise<void>;
|
|
31
31
|
/** Send a control-priority frame (WINDOW/CLOSE/RESET) immediately. */
|
|
32
32
|
sendControlFrame(frame: Uint8Array): void;
|
|
33
|
-
/** Called when the stream is fully closed so the connection can retire its id. */
|
|
33
|
+
/** Called when the stream is fully closed so the connection can retire its id (a connection teardown still reaches it until it is destroyed). */
|
|
34
34
|
retireStream(streamId: number): void;
|
|
35
|
+
/** Called when the stream starts holding a write callback, so the connection holds a retired stream strongly until that callback is settled (a no-op for one not yet retired). Optional: a host that tracks no retired streams has nothing to pin. */
|
|
36
|
+
pinRetired?(streamId: number): void;
|
|
35
37
|
}
|
|
36
38
|
export declare class MixerStream extends Duplex {
|
|
37
39
|
readonly id: number;
|
|
@@ -48,7 +50,7 @@ export declare class MixerStream extends Duplex {
|
|
|
48
50
|
/** Bytes queued via _write, waiting on credit; drives backpressure. */
|
|
49
51
|
private writeQueue;
|
|
50
52
|
private draining;
|
|
51
|
-
/** Write callbacks (_write's own terminal-error branch, or
|
|
53
|
+
/** Write callbacks (_write's own terminal-error branch, or failWrite()) whose error must wait until the read side has finished delivering buffered data and emitted 'end' -- see terminateNoThrow's doc comment. Non-null exactly while that wait is pending; flushed (and reset to null) from _destroy(), or from the 'end' listener failWrite() installs. */
|
|
52
54
|
private heldWriteCallbacks;
|
|
53
55
|
/** Set once this stream is RESET -- by the peer (handleReset), the SDK (abort()), or the app itself (reset()); undefined until then. Set even when no `'error'` listener is attached. */
|
|
54
56
|
resetCode?: number;
|
|
@@ -62,6 +64,35 @@ export declare class MixerStream extends Duplex {
|
|
|
62
64
|
_destroy(err: Error | null, callback: (error?: Error | null) => void): void;
|
|
63
65
|
private pumpWriteQueue;
|
|
64
66
|
private drainWriteQueue;
|
|
67
|
+
/**
|
|
68
|
+
* Settles a failed write's callback with `failure` -- now, or held until
|
|
69
|
+
* the read side can no longer be hurt by it. Calling a write callback with
|
|
70
|
+
* an error marks the READABLE side errored too (Node's own Writable/Duplex
|
|
71
|
+
* machinery), which drops whatever is still buffered and blocks 'end'.
|
|
72
|
+
*
|
|
73
|
+
* - terminateNoThrow is already holding write errors for the read side
|
|
74
|
+
* (`heldWriteCallbacks` non-null): join that hold -- see its doc comment.
|
|
75
|
+
* - The peer's CLOSE has arrived and 'end' hasn't fired yet, whatever this
|
|
76
|
+
* side's own write state (`half_closed_remote`, or `closed` after
|
|
77
|
+
* closeWrite()): the read side may still be delivering buffered data, so
|
|
78
|
+
* hold the callback until 'end', without relying on teardown to flush it
|
|
79
|
+
* -- there may be no teardown at all. A connection teardown that does
|
|
80
|
+
* come (it also reaches a stream closeWrite() retired) flushes it once
|
|
81
|
+
* nothing is left unread; so do destroy()/reset(). `failure` is the
|
|
82
|
+
* fallback for a flush with no terminalError of its own (always, on a
|
|
83
|
+
* stream CLOSE'd both ways -- see terminateNoThrow).
|
|
84
|
+
* - Otherwise (peer still sending, 'end' already fired or never will --
|
|
85
|
+
* destroyed, or already errored): fail it now.
|
|
86
|
+
*
|
|
87
|
+
* Node's Writable machinery re-emits a write callback's error as 'error',
|
|
88
|
+
* so -- same rationale as terminateNoThrow() -- the internal no-op listener
|
|
89
|
+
* is attached first if nothing else is listening: a failure is also
|
|
90
|
+
* reachable before terminateNoThrow() has run at all (the connection's
|
|
91
|
+
* writer failed this chunk's socket write, and teardown follows from the
|
|
92
|
+
* socket's own 'close'), and a dying connection must not crash a consumer
|
|
93
|
+
* that never attached its own 'error'.
|
|
94
|
+
*/
|
|
95
|
+
private failWrite;
|
|
65
96
|
/** Waits until send credit is available, then reserves and returns min(want, sendWindow, MAX_CHUNK). */
|
|
66
97
|
private reserveSendCredit;
|
|
67
98
|
private wakeSendWaiters;
|
|
@@ -83,16 +114,37 @@ export declare class MixerStream extends Duplex {
|
|
|
83
114
|
* never entered it there.
|
|
84
115
|
*/
|
|
85
116
|
read(size?: number): unknown;
|
|
117
|
+
/**
|
|
118
|
+
* Both directions CLOSE'd cleanly (closeWrite() + the peer's CLOSE, in
|
|
119
|
+
* either order): the stream is retired, so only a connection teardown
|
|
120
|
+
* (which may never come) would otherwise reach it, and 'close' needs a
|
|
121
|
+
* destroy() on an `autoDestroy: false` Duplex. Mirrors
|
|
122
|
+
* what autoDestroy itself would do: destroy once the readable has emitted
|
|
123
|
+
* 'end' (a tick later, like failWrite()'s hold, so every 'end' listener
|
|
124
|
+
* runs first and 'end' always precedes 'close'), and, when the write side
|
|
125
|
+
* was closed by end(), once 'finish' has fired too -- destroying inside
|
|
126
|
+
* _final() would suppress 'finish' and turn finished()/pipeline() into a
|
|
127
|
+
* premature close. A readable that already errored never emits 'end', so
|
|
128
|
+
* that destroys right away. A consumer that never reads never sees 'end',
|
|
129
|
+
* and so never 'close' -- same as any other Readable.
|
|
130
|
+
*/
|
|
131
|
+
private destroyWhenDone;
|
|
86
132
|
private maybeDeliverEOF;
|
|
87
|
-
/** True once something is listening for `'error'`: gates attaching the internal no-op `'error'` listener (terminateNoThrow,
|
|
133
|
+
/** True once something is listening for `'error'`: gates attaching the internal no-op `'error'` listener (terminateNoThrow, failWrite). */
|
|
88
134
|
private hasErrorListener;
|
|
89
|
-
/**
|
|
135
|
+
/**
|
|
136
|
+
* Sends CLOSE: "I will send no more DATA on this stream." end() is sugar
|
|
137
|
+
* for this via _final. A write still waiting on send credit can never go
|
|
138
|
+
* out now, so it is woken to fail with STREAM_CLOSED (reserveSendCredit)
|
|
139
|
+
* instead of waiting on a WINDOW that, once this stream is retired, would
|
|
140
|
+
* never reach it.
|
|
141
|
+
*/
|
|
90
142
|
closeWrite(): void;
|
|
91
143
|
/**
|
|
92
144
|
* Sends CLOSE (if not already sent) and stops delivering further reads. If
|
|
93
145
|
* the peer has not yet half-closed its own send side, a plain closeWrite()
|
|
94
146
|
* would leave it writing into a window nobody drains, so close() also
|
|
95
|
-
* RESETs with CANCEL in that case (mirrors go/wsmixer/stream.go Close()).
|
|
147
|
+
* RESETs with CANCEL in that case (mirrors ws-mixer-go/wsmixer/stream.go Close()).
|
|
96
148
|
*/
|
|
97
149
|
close(): void;
|
|
98
150
|
/**
|
|
@@ -114,7 +166,7 @@ export declare class MixerStream extends Duplex {
|
|
|
114
166
|
* an SDK-detected violation (abort()), `reset()` does NOT emit `'reset'`.
|
|
115
167
|
*/
|
|
116
168
|
reset(code: number | string, message?: string): void;
|
|
117
|
-
/** Shared implementation behind reset()/abort(); returns false (
|
|
169
|
+
/** Shared implementation behind reset()/abort(); returns false (nothing sent) if the stream was already closed. */
|
|
118
170
|
private applyReset;
|
|
119
171
|
/**
|
|
120
172
|
* Wraps this stream as Web Streams API `{ readable, writable }`, e.g. for
|