@zlink-systems/stream-connector 0.13.0 → 0.15.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.
@@ -1,7 +1,7 @@
1
1
  import type { Disposable } from './ZlinkStreamInterfaces';
2
2
  import type { RequiredZlinkStreamConnectorOptions } from './ZlinkStreamConnectorOptions';
3
3
  import type { ZlinkStreamRequestCall, ZlinkStreamSendCall, ZlinkStreamExpectNoneCall, ZlinkStreamSequenceCall, ZlinkStreamWaitCall } from './Calls/ZlinkStreamCalls';
4
- import type { ZlinkStreamConnectionStateChanged, ZlinkStreamEncodedPayload, ZlinkStreamError, ZlinkStreamInboundObservation, ZlinkStreamMessage } from './ZlinkStreamModels';
4
+ import type { ZlinkStreamConnectionStateChanged, ZlinkStreamEncodedPayload, ZlinkStreamError, ZlinkStreamMessage } from './ZlinkStreamModels';
5
5
  import type { ZlinkStreamCloseReason, ZlinkStreamConnectionState, ZlinkStreamDiagnosticsLevel } from './ZlinkStreamEnums';
6
6
  export interface ZlinkStreamConnector {
7
7
  readonly isConnected: boolean;
@@ -30,7 +30,6 @@ export interface ZlinkStreamConnector {
30
30
  dispatch(signal?: AbortSignal): Promise<void>;
31
31
  send(payload: unknown, messageType?: Function): ZlinkStreamSendCall;
32
32
  request(payload: unknown, messageType?: Function): ZlinkStreamRequestCall;
33
- observeInbound(observer: (observation: ZlinkStreamInboundObservation, signal?: AbortSignal) => Promise<void> | void): Disposable;
34
33
  on<TPayload = ZlinkStreamEncodedPayload>(name: string, handler: (message: ZlinkStreamMessage<TPayload>, signal?: AbortSignal) => Promise<void> | void, messageType?: Function): Disposable;
35
34
  waitFor<TPayload = ZlinkStreamEncodedPayload>(name: string): ZlinkStreamWaitCall<TPayload>;
36
35
  expectNone<TPayload = ZlinkStreamEncodedPayload>(name: string): ZlinkStreamExpectNoneCall<TPayload>;
@@ -12,9 +12,6 @@ export interface ZlinkStreamConnectorOptions {
12
12
  readonly reconnect?: ZlinkStreamReconnectOptions;
13
13
  readonly maxSendPayloadSize?: number;
14
14
  readonly maxReceivePayloadSize?: number;
15
- readonly maxReceivedMessages?: number;
16
- readonly maxInboundObserverNotifications?: number;
17
- readonly maxInboundObserverPayloadPreviewBytes?: number;
18
15
  readonly dispatchMode?: ZlinkStreamDispatchMode;
19
16
  readonly compression?: ZlinkStreamCompression;
20
17
  readonly compressionCodec?: ZlinkStreamCompressionCodec;
@@ -85,9 +82,6 @@ export interface RequiredZlinkStreamConnectorOptions {
85
82
  readonly reconnect: Required<ZlinkStreamReconnectOptions>;
86
83
  readonly maxSendPayloadSize: number;
87
84
  readonly maxReceivePayloadSize: number;
88
- readonly maxReceivedMessages: number;
89
- readonly maxInboundObserverNotifications: number;
90
- readonly maxInboundObserverPayloadPreviewBytes: number;
91
85
  readonly dispatchMode: ZlinkStreamDispatchMode;
92
86
  readonly compression: ZlinkStreamCompression;
93
87
  readonly compressionCodec?: ZlinkStreamCompressionCodec;
@@ -54,9 +54,6 @@ export declare enum ZlinkStreamErrorCode {
54
54
  CompressionFailed = "compressionFailed",
55
55
  DecompressionFailed = "decompressionFailed",
56
56
  UserCallbackFailed = "userCallbackFailed",
57
- ObserverFailed = "observer-failed",
58
- ObserverDropped = "observer-dropped",
59
- ReceivedMessageDropped = "received-message-dropped",
60
57
  RemoteError = "remoteError"
61
58
  }
62
59
  export declare enum ZlinkStreamConnectionState {
@@ -42,19 +42,6 @@ export interface ZlinkStreamConnectionStateChanged {
42
42
  readonly current: ZlinkStreamConnectionState;
43
43
  readonly error?: ZlinkStreamError;
44
44
  }
45
- export interface ZlinkStreamInboundObservation {
46
- readonly kind: ZlinkStreamMessageKind;
47
- readonly name: string;
48
- readonly codec: ZlinkStreamCodec;
49
- readonly requestSeq?: bigint;
50
- readonly flowId?: string;
51
- readonly flowOrigin?: ZlinkFlowOrigin;
52
- readonly metadata: ZlinkStreamMetadata;
53
- readonly payloadLength: number;
54
- readonly isCompressed: boolean;
55
- readonly receivedAt: Date;
56
- readonly payloadPreview: Uint8Array;
57
- }
58
45
  export interface ZlinkStreamResult {
59
46
  readonly isSuccess: boolean;
60
47
  readonly error?: ZlinkStreamError;
@@ -3,7 +3,7 @@ export type { ZlinkFlowOrigin, ZlinkStreamCloseReason } from './ZlinkStreamEnums
3
3
  export * from './ZlinkStreamConnectorOptions';
4
4
  export * from './ZlinkStreamInterfaces';
5
5
  export * from './ZlinkStreamMetadata';
6
- export type { ZlinkStreamEncodedPayload, ZlinkStreamFlow, ZlinkStreamMessage, ZlinkStreamError, ZlinkStreamConnectionStateChanged, ZlinkStreamInboundObservation, ZlinkStreamResult, ZlinkStreamResultOf } from './ZlinkStreamModels';
6
+ export type { ZlinkStreamEncodedPayload, ZlinkStreamFlow, ZlinkStreamMessage, ZlinkStreamError, ZlinkStreamConnectionStateChanged, ZlinkStreamResult, ZlinkStreamResultOf } from './ZlinkStreamModels';
7
7
  export { ZlinkStreamException } from './ZlinkStreamModels';
8
8
  export * from './ZlinkStreamJsonCodec';
9
9
  export * from './IZlinkStreamConnector';
@@ -1,4 +1,4 @@
1
- import { Disposable, RequiredZlinkStreamConnectorOptions, ZlinkStreamConnectionState, ZlinkStreamConnectionStateChanged, ZlinkStreamConnector, ZlinkStreamConnectorOptions, ZlinkStreamDiagnosticsLevel, ZlinkStreamEncodedPayload, ZlinkStreamError, ZlinkStreamExpectNoneCall, ZlinkStreamFlow, ZlinkStreamInboundObservation, ZlinkStreamMessage, ZlinkStreamMessageKind, ZlinkStreamMetadata, ZlinkStreamRequestCall, ZlinkStreamSendCall, ZlinkStreamSequenceCall, ZlinkStreamWaitCall } from '../Contracts';
1
+ import { Disposable, RequiredZlinkStreamConnectorOptions, ZlinkStreamConnectionState, ZlinkStreamConnectionStateChanged, ZlinkStreamConnector, ZlinkStreamConnectorOptions, ZlinkStreamDiagnosticsLevel, ZlinkStreamEncodedPayload, ZlinkStreamError, ZlinkStreamExpectNoneCall, ZlinkStreamFlow, ZlinkStreamMessage, ZlinkStreamMessageKind, ZlinkStreamMetadata, ZlinkStreamRequestCall, ZlinkStreamSendCall, ZlinkStreamSequenceCall, ZlinkStreamWaitCall } from '../Contracts';
2
2
  export declare class DefaultZlinkStreamConnector implements ZlinkStreamConnector {
3
3
  static readonly heartbeatPingName = "$zlink.heartbeat.ping";
4
4
  static readonly heartbeatPongName = "$zlink.heartbeat.pong";
@@ -9,7 +9,6 @@ export declare class DefaultZlinkStreamConnector implements ZlinkStreamConnector
9
9
  private readonly pendingRequests;
10
10
  private readonly frameSender;
11
11
  private readonly receiveDispatcher;
12
- private readonly inboundObservers;
13
12
  private readonly diagnosticsLevelCell;
14
13
  readonly options: RequiredZlinkStreamConnectorOptions;
15
14
  constructor(options: ZlinkStreamConnectorOptions);
@@ -43,7 +42,6 @@ export declare class DefaultZlinkStreamConnector implements ZlinkStreamConnector
43
42
  dispatch(signal?: AbortSignal): Promise<void>;
44
43
  send(payload: unknown, messageType?: Function): ZlinkStreamSendCall;
45
44
  request(payload: unknown, messageType?: Function): ZlinkStreamRequestCall;
46
- observeInbound(observer: (observation: ZlinkStreamInboundObservation, signal?: AbortSignal) => Promise<void> | void): Disposable;
47
45
  on<TPayload = ZlinkStreamEncodedPayload>(name: string, handler: (message: ZlinkStreamMessage<TPayload>, signal?: AbortSignal) => Promise<void> | void, messageType?: Function): Disposable;
48
46
  waitFor<TPayload = ZlinkStreamEncodedPayload>(name: string): ZlinkStreamWaitCall<TPayload>;
49
47
  expectNone<TPayload = ZlinkStreamEncodedPayload>(name: string): ZlinkStreamExpectNoneCall<TPayload>;
@@ -5,15 +5,20 @@ import type { ZlinkStreamConnectorEvents } from './ZlinkStreamConnectorEvents';
5
5
  import type { ZlinkStreamFrameSender } from './ZlinkStreamFrameSender';
6
6
  import type { ZlinkStreamPendingRequests } from './ZlinkStreamPendingRequests';
7
7
  import type { ZlinkStreamReceiveDispatcher } from './ZlinkStreamReceiveDispatcher';
8
+ import type { ZlinkStreamReceivedMessages } from './ZlinkStreamReceivedMessages';
8
9
  import type { ZlinkStreamRuntimeMetrics } from './ZlinkStreamRuntimeMetrics';
9
10
  export declare class ZlinkStreamConnectorLifecycle {
10
11
  private readonly options;
11
12
  private readonly pendingRequests;
12
13
  private readonly frameSender;
13
14
  private readonly receiveDispatcher;
15
+ private readonly receivedMessages;
14
16
  private readonly events;
15
17
  private readonly metrics;
16
18
  private receiveLoopAbort;
19
+ private receiveLoopSleeping;
20
+ private receiveLoopWake;
21
+ private readonly receiveLoopSettled;
17
22
  private currentConnection;
18
23
  private connectionGeneration;
19
24
  private currentState;
@@ -26,7 +31,7 @@ export declare class ZlinkStreamConnectorLifecycle {
26
31
  private disconnectedPublished;
27
32
  private closeReasonValue?;
28
33
  private lateConnectCleanupError;
29
- constructor(options: RequiredZlinkStreamConnectorOptions, pendingRequests: ZlinkStreamPendingRequests, frameSender: ZlinkStreamFrameSender, receiveDispatcher: ZlinkStreamReceiveDispatcher, events: ZlinkStreamConnectorEvents, metrics: ZlinkStreamRuntimeMetrics);
34
+ constructor(options: RequiredZlinkStreamConnectorOptions, pendingRequests: ZlinkStreamPendingRequests, frameSender: ZlinkStreamFrameSender, receiveDispatcher: ZlinkStreamReceiveDispatcher, receivedMessages: ZlinkStreamReceivedMessages, events: ZlinkStreamConnectorEvents, metrics: ZlinkStreamRuntimeMetrics);
30
35
  get isConnected(): boolean;
31
36
  get state(): ZlinkStreamConnectionState;
32
37
  get closeReason(): ZlinkStreamCloseReason | undefined;
@@ -35,6 +40,15 @@ export declare class ZlinkStreamConnectorLifecycle {
35
40
  close(signal?: AbortSignal): Promise<void>;
36
41
  serverClosing(reason: ZlinkStreamCloseReason): Promise<void>;
37
42
  private closeOnce;
43
+ /**
44
+ * Spec stream-connector 32 §7: `dispatch` runs the callbacks the receive loop
45
+ * queued, it does not drive the transport. Receiving is the receive loop's
46
+ * job in both dispatch modes, which is what lets a `Manual` consumer complete
47
+ * a `waitFor` without pumping, and what keeps this call from blocking on an
48
+ * idle connection. In `Manual` it first lets the loop settle whatever has
49
+ * already arrived, so a packet the transport is holding is delivered by this
50
+ * pump rather than the next one.
51
+ */
38
52
  dispatch(signal?: AbortSignal): Promise<void>;
39
53
  connectionForSend(): ZlinkStreamConnection;
40
54
  private dispatchAvailable;
@@ -44,6 +58,9 @@ export declare class ZlinkStreamConnectorLifecycle {
44
58
  private startReceiveLoop;
45
59
  private stopReceiveLoop;
46
60
  private runReceiveLoop;
61
+ private sleepUntilWork;
62
+ private settleReceiveLoop;
63
+ private releaseReceiveLoopSettled;
47
64
  private shouldContinueReceiveLoop;
48
65
  private runHeartbeatTick;
49
66
  private disconnectForTransportFailure;
@@ -2,7 +2,6 @@ import type { ZlinkStreamConnection } from '../Contracts';
2
2
  import type { ZlinkStreamFrameProtocol } from './Protocol/ZlinkStreamFrameProtocol';
3
3
  import type { ZlinkStreamConnectorEvents } from './ZlinkStreamConnectorEvents';
4
4
  import type { ZlinkStreamFrameSender } from './ZlinkStreamFrameSender';
5
- import type { ZlinkStreamInboundObservers } from './ZlinkStreamInboundObservers';
6
5
  import type { ZlinkStreamPendingRequests } from './ZlinkStreamPendingRequests';
7
6
  import type { ZlinkStreamReceivedMessages } from './ZlinkStreamReceivedMessages';
8
7
  import type { ZlinkFlowContext } from './ZlinkFlowContext';
@@ -15,14 +14,13 @@ export interface ZlinkStreamReceiveResult {
15
14
  export declare class ZlinkStreamReceiveDispatcher {
16
15
  private readonly protocol;
17
16
  private readonly pendingRequests;
18
- private readonly inboundObservers;
19
17
  private readonly receivedMessages;
20
18
  private readonly frameSender;
21
19
  private readonly events;
22
20
  private readonly flowContext;
23
21
  private readonly metrics;
24
22
  private readonly serverClosing?;
25
- constructor(protocol: ZlinkStreamFrameProtocol, pendingRequests: ZlinkStreamPendingRequests, inboundObservers: ZlinkStreamInboundObservers, receivedMessages: ZlinkStreamReceivedMessages, frameSender: ZlinkStreamFrameSender, events: ZlinkStreamConnectorEvents, flowContext: ZlinkFlowContext, metrics: ZlinkStreamRuntimeMetrics, serverClosing?: ((reason: ZlinkStreamCloseReason) => Promise<void>) | undefined);
23
+ constructor(protocol: ZlinkStreamFrameProtocol, pendingRequests: ZlinkStreamPendingRequests, receivedMessages: ZlinkStreamReceivedMessages, frameSender: ZlinkStreamFrameSender, events: ZlinkStreamConnectorEvents, flowContext: ZlinkFlowContext, metrics: ZlinkStreamRuntimeMetrics, serverClosing?: ((reason: ZlinkStreamCloseReason) => Promise<void>) | undefined);
26
24
  readAndDispatch(connection: ZlinkStreamConnection | undefined, signal?: AbortSignal, isCurrent?: () => boolean): Promise<ZlinkStreamReceiveResult>;
27
25
  private dispatch;
28
26
  private dispatchControl;
@@ -1,24 +1,51 @@
1
1
  import { Disposable, ZlinkStreamEncodedPayload, ZlinkStreamMessage } from '../Contracts';
2
2
  import type { ZlinkStreamConnectorEvents } from './ZlinkStreamConnectorEvents';
3
3
  type EncodedMessageHandler = (message: ZlinkStreamMessage<ZlinkStreamEncodedPayload>, signal?: AbortSignal) => Promise<void> | void;
4
+ /**
5
+ * A wait surface (`waitFor`, `expectNone`, `waitForSequence`) reading the queue
6
+ * directly. It returns true when it consumed the message and must not throw:
7
+ * a failed predicate is reported through the waiting call, not to the queue.
8
+ */
9
+ type EncodedMessageObserver = (message: ZlinkStreamMessage<ZlinkStreamEncodedPayload>) => boolean;
4
10
  export declare class ZlinkStreamReceivedMessages {
5
- private readonly capacity;
6
11
  private readonly events;
12
+ private readonly deliverOnArrival;
7
13
  private readonly handlers;
14
+ private readonly observers;
8
15
  private readonly queue;
9
16
  private queueHead;
10
17
  private queuedCount;
11
18
  private drainTask;
12
- private dropReportPending;
13
- constructor(capacity: number, events: ZlinkStreamConnectorEvents);
19
+ /**
20
+ * @param deliverOnArrival `Immediate` runs registered handlers on the receive
21
+ * path; `Manual` leaves them queued until {@link pump} runs them on the
22
+ * caller's thread (spec stream-connector 32 §7). Wait surfaces observe the
23
+ * queue in both modes, so they never depend on this flag.
24
+ */
25
+ constructor(events: ZlinkStreamConnectorEvents, deliverOnArrival: boolean);
14
26
  on(name: string, handler: EncodedMessageHandler): Disposable;
27
+ /**
28
+ * Registers a wait surface over the receive queue. Spec stream-connector 32
29
+ * §7: these are not registered callbacks — they observe and consume the
30
+ * packets the queue has not delivered yet, in both dispatch modes, so
31
+ * `Manual` needs no dispatch pump to complete a wait. The queue is scanned in
32
+ * a microtask so a message that arrived before the wait started is still
33
+ * observed, and so the caller has its subscription in hand by then.
34
+ */
35
+ observe(name: string, observer: EncodedMessageObserver): Disposable;
15
36
  enqueue(message: ZlinkStreamMessage<ZlinkStreamEncodedPayload>, signal?: AbortSignal): void;
37
+ /**
38
+ * Runs the registered handlers the receive path left queued. `Manual` calls
39
+ * this from `dispatch`; `Immediate` has already drained on arrival.
40
+ */
41
+ pump(): Promise<void>;
42
+ private offerQueued;
16
43
  private scheduleDrain;
17
44
  private drain;
45
+ private removeAt;
18
46
  private findDeliverableIndex;
19
47
  private hasQueuedMessage;
20
48
  private advanceHead;
21
49
  private compactQueue;
22
- private reportDropped;
23
50
  }
24
51
  export {};