@api.global/typedsocket 5.1.2 → 6.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.
@@ -0,0 +1,187 @@
1
+ import type * as plugins from './typedsocket.plugins.js';
2
+ import type { NATIVE_BYTE_FRAME_TYPES, NATIVE_BYTE_PROTOCOL } from './nativebytes.constants.js';
3
+ export type TNativeByteCapabilityMode = 'disabled' | 'optional' | 'required';
4
+ export type TNativeByteRole = 'producer' | 'consumer';
5
+ export type TNativeByteAuthorityOperation = 'open' | 'data' | 'fin' | 'confirm' | 'reject';
6
+ export interface INativeByteDescriptorTransport {
7
+ readonly [key: string]: plugins.typedrequestInterfaces.TNativeStreamTransportDescriptorPayload;
8
+ readonly protocolMajor: 6;
9
+ readonly role: 'producer';
10
+ readonly streamId: string;
11
+ readonly capability: string;
12
+ readonly byteLength: number;
13
+ readonly sha256: string;
14
+ readonly contentType: string;
15
+ readonly expiresAt: number;
16
+ readonly initialWindowBytes: number;
17
+ }
18
+ export interface INativeByteDescriptor extends plugins.typedrequestInterfaces.INativeByteStreamDescriptor {
19
+ readonly protocol: typeof NATIVE_BYTE_PROTOCOL;
20
+ readonly transport: INativeByteDescriptorTransport;
21
+ }
22
+ export interface INativeByteReceipt {
23
+ readonly streamId: string;
24
+ readonly byteLength: number;
25
+ readonly sha256: string;
26
+ readonly contentType: string;
27
+ readonly durable: true;
28
+ }
29
+ export interface INativeByteAuthorizationBinding extends INativeByteAuthorityRevisions {
30
+ readonly principalId: string;
31
+ readonly revalidate: TNativeByteRevalidate;
32
+ }
33
+ export interface INativeByteAuthorizationContext {
34
+ readonly target: plugins.IWebSocketPeer;
35
+ readonly manifest: plugins.typedrequestInterfaces.INativeByteStreamManifest;
36
+ }
37
+ export interface INativeByteAuthorizationAdapter {
38
+ bind(authorizationArg: unknown, contextArg: Readonly<INativeByteAuthorizationContext>): INativeByteAuthorizationBinding;
39
+ }
40
+ export interface INativeByteCreateVirtualStreamOptions {
41
+ readonly protocol: 'native-byte-v1';
42
+ readonly direction: 'receive';
43
+ readonly target: {
44
+ readonly peer: plugins.IWebSocketPeer;
45
+ } | plugins.IWebSocketPeer;
46
+ readonly byteLength: number;
47
+ readonly sha256: string;
48
+ readonly contentType: string;
49
+ readonly authorization: unknown;
50
+ readonly initialWindowBytes?: number;
51
+ }
52
+ export interface INativeByteAuthorityRevisions {
53
+ readonly credentialRevision: string;
54
+ readonly configRevision: string;
55
+ readonly bindingRevision: string;
56
+ }
57
+ export type TNativeByteConnectionBinding = {
58
+ readonly side: 'client';
59
+ readonly generation: number;
60
+ readonly webSocket: WebSocket;
61
+ } | {
62
+ readonly side: 'server';
63
+ readonly peer: plugins.IWebSocketPeer;
64
+ };
65
+ export interface INativeByteRevalidationContext extends INativeByteAuthorityRevisions {
66
+ readonly operation: TNativeByteAuthorityOperation;
67
+ readonly descriptor: INativeByteDescriptor;
68
+ readonly connection: TNativeByteConnectionBinding;
69
+ readonly abortSignal: AbortSignal;
70
+ readonly deadline: number;
71
+ }
72
+ export type TNativeByteRevalidate = (contextArg: INativeByteRevalidationContext) => boolean | Promise<boolean>;
73
+ export interface INativeByteCreateReceiveGrantOptions extends INativeByteAuthorityRevisions {
74
+ readonly principalId: string;
75
+ readonly byteLength: number;
76
+ readonly sha256: string;
77
+ readonly contentType: string;
78
+ readonly revalidate: TNativeByteRevalidate;
79
+ readonly target?: {
80
+ readonly peer: plugins.IWebSocketPeer;
81
+ } | plugins.IWebSocketPeer;
82
+ readonly initialWindowBytes?: number;
83
+ }
84
+ export interface INativeByteOpenSenderOptions {
85
+ readonly target?: {
86
+ readonly peer: plugins.IWebSocketPeer;
87
+ } | plugins.IWebSocketPeer;
88
+ }
89
+ export interface INativeByteReceiveGrant {
90
+ readonly descriptor: INativeByteDescriptor;
91
+ readonly stream: INativeByteReceiverLike;
92
+ readonly opened: Promise<INativeByteReceiverLike>;
93
+ readonly revoke: (reasonArg?: unknown) => Promise<void>;
94
+ readonly dispose: () => void;
95
+ }
96
+ export interface INativeByteReceiverLike extends plugins.typedrequestInterfaces.INativeStreamTransportEndpoint {
97
+ readonly protocol: 'native-byte-v1';
98
+ readonly direction: 'receive';
99
+ readonly manifest: plugins.typedrequestInterfaces.INativeByteStreamManifest;
100
+ readonly readable: ReadableStream<Uint8Array>;
101
+ readonly completion: Promise<INativeByteReceipt>;
102
+ confirmDurable(): Promise<INativeByteReceipt>;
103
+ reject(reasonArg?: unknown): Promise<void>;
104
+ }
105
+ export interface INativeByteSenderLike extends plugins.typedrequestInterfaces.INativeStreamTransportEndpoint {
106
+ readonly protocol: 'native-byte-v1';
107
+ readonly direction: 'send';
108
+ readonly manifest: plugins.typedrequestInterfaces.INativeByteStreamManifest;
109
+ readonly writable: WritableStream<Uint8Array>;
110
+ readonly completion: Promise<INativeByteReceipt>;
111
+ }
112
+ export interface INativeByteCapabilityStatus {
113
+ readonly protocolMajor: 6;
114
+ readonly capabilities: readonly (typeof NATIVE_BYTE_PROTOCOL)[];
115
+ readonly connection: 'none' | 'client' | 'server';
116
+ }
117
+ export interface INativeByteStats {
118
+ readonly connection: 'none' | 'client' | 'server';
119
+ readonly negotiated: boolean;
120
+ readonly activeStreams: number;
121
+ readonly receiveGrants: number;
122
+ readonly queuedPayloadBytes: number;
123
+ readonly rawQueueFrames: number;
124
+ readonly rawQueueBytes: number;
125
+ readonly processingRawBytes: number;
126
+ readonly outboundControlFrames: number;
127
+ readonly outboundDataFrames: number;
128
+ readonly tombstones: number;
129
+ readonly retainedRevalidations: number;
130
+ readonly serverConnections: number;
131
+ readonly serverStreams: number;
132
+ readonly serverRetainedBytes: number;
133
+ readonly serverRetainedRevalidations: number;
134
+ }
135
+ export interface INativeByteRuntime {
136
+ now(): number;
137
+ randomBytes(lengthArg: number): Uint8Array;
138
+ setTimer(callbackArg: () => void, delayMsArg: number): unknown;
139
+ clearTimer(timerArg: unknown): void;
140
+ scheduleMacrotask(callbackArg: () => void): unknown;
141
+ }
142
+ export type TNativeByteOpenFrame = {
143
+ readonly type: typeof NATIVE_BYTE_FRAME_TYPES.OPEN;
144
+ readonly streamId: string;
145
+ readonly capability: string;
146
+ readonly byteLength: number;
147
+ readonly sha256: string;
148
+ readonly contentType: string;
149
+ readonly initialWindowBytes: number;
150
+ };
151
+ export type TNativeByteOpenAckFrame = {
152
+ readonly type: typeof NATIVE_BYTE_FRAME_TYPES.OPEN_ACK;
153
+ readonly streamId: string;
154
+ readonly receiveLimitOffset: number;
155
+ };
156
+ export type TNativeByteDataFrame = {
157
+ readonly type: typeof NATIVE_BYTE_FRAME_TYPES.DATA;
158
+ readonly streamId: string;
159
+ readonly sequence: number;
160
+ readonly offset: number;
161
+ readonly payload: Uint8Array;
162
+ };
163
+ export type TNativeByteAckFrame = {
164
+ readonly type: typeof NATIVE_BYTE_FRAME_TYPES.ACK;
165
+ readonly streamId: string;
166
+ readonly acknowledgedOffset: number;
167
+ readonly receiveLimitOffset: number;
168
+ };
169
+ export type TNativeByteFinFrame = {
170
+ readonly type: typeof NATIVE_BYTE_FRAME_TYPES.FIN;
171
+ readonly streamId: string;
172
+ readonly byteLength: number;
173
+ readonly sha256: string;
174
+ };
175
+ export type TNativeByteFinAckFrame = {
176
+ readonly type: typeof NATIVE_BYTE_FRAME_TYPES.FIN_ACK;
177
+ readonly streamId: string;
178
+ readonly byteLength: number;
179
+ readonly sha256: string;
180
+ };
181
+ export type TNativeByteResetFrame = {
182
+ readonly type: typeof NATIVE_BYTE_FRAME_TYPES.RESET;
183
+ readonly streamId: string;
184
+ readonly code: number;
185
+ readonly reason: string;
186
+ };
187
+ export type TNativeByteFrame = TNativeByteOpenFrame | TNativeByteOpenAckFrame | TNativeByteDataFrame | TNativeByteAckFrame | TNativeByteFinFrame | TNativeByteFinAckFrame | TNativeByteResetFrame;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmF0aXZlYnl0ZXMudHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9uYXRpdmVieXRlcy50eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiIn0=
@@ -1,6 +1,52 @@
1
1
  import * as plugins from './typedsocket.plugins.js';
2
+ import { NativeByteManager } from './nativebytes.manager.js';
3
+ import type { INativeByteAuthorizationAdapter, INativeByteCreateVirtualStreamOptions, TNativeByteCapabilityMode } from './nativebytes.types.js';
4
+ import type { ITypedSocketClientTagPolicy } from './typedsocket.tags.js';
2
5
  export type TTypedSocketSide = 'server' | 'client';
3
6
  export type TConnectionStatus = 'new' | 'connecting' | 'connected' | 'disconnected' | 'reconnecting';
7
+ export declare const TYPEDSOCKET_MAX_TEXT_FRAME_BYTES: number;
8
+ export declare const TYPEDSOCKET_MAX_QUEUED_TEXT_FRAMES = 64;
9
+ export declare const TYPEDSOCKET_MAX_QUEUED_TEXT_BYTES: number;
10
+ export declare const TYPEDSOCKET_MAX_CONCURRENT_CLIENT_HANDLERS = 16;
11
+ export declare const TYPEDSOCKET_MAX_RETAINED_CLIENT_CALLBACKS = 64;
12
+ export declare const TYPEDSOCKET_MAX_PENDING_CLIENT_REQUESTS = 1024;
13
+ export declare const TYPEDSOCKET_MAX_OUTBOUND_BUFFERED_BYTES: number;
14
+ export declare const TYPEDSOCKET_MAX_METHOD_NAME_BYTES = 256;
15
+ export declare const TYPEDSOCKET_MAX_CORRELATION_ID_BYTES = 256;
16
+ export declare const TYPEDSOCKET_MAX_REQUEST_TIMEOUT_MS: number;
17
+ export declare const TYPEDSOCKET_MAX_CONNECTION_RESTORE_TIMEOUT_MS = 10000;
18
+ export declare const TYPEDSOCKET_MAX_RECONNECT_RETRIES = 100;
19
+ export declare const TYPEDSOCKET_MAX_RECONNECT_BACKOFF_MS = 60000;
20
+ export declare const TYPEDSOCKET_MAX_RETAINED_CLIENT_TAG_MUTATIONS_PER_NAME = 8;
21
+ export declare const TYPEDSOCKET_MAX_RETAINED_CLIENT_TAG_MUTATIONS = 64;
22
+ export declare const TYPEDSOCKET_MAX_PENDING_SERVER_REQUESTS_PER_PEER = 64;
23
+ export declare const TYPEDSOCKET_MAX_PENDING_SERVER_REQUESTS = 1024;
24
+ export declare const TYPEDSOCKET_MAX_RETAINED_SERVER_INTERESTS_PER_PEER = 8;
25
+ export declare const TYPEDSOCKET_MAX_RETAINED_SERVER_INTERESTS = 64;
26
+ export interface ITypedSocketClientLimits {
27
+ readonly textFrameBytes: number;
28
+ readonly queuedTextFrames: number;
29
+ readonly queuedTextBytes: number;
30
+ readonly concurrentHandlers: number;
31
+ readonly retainedCallbacks: number;
32
+ readonly pendingRequests: number;
33
+ readonly outboundBufferedBytes: number;
34
+ readonly requestTimeoutMs: number;
35
+ readonly connectionRestoreTimeoutMs: number;
36
+ }
37
+ export interface ITypedSocketConnectionRestoreContext {
38
+ readonly connectionId: string;
39
+ readonly abortSignal: AbortSignal;
40
+ readonly deadline: number;
41
+ readonly createTypedRequest: TTypedSocketRestoreRequestFactory;
42
+ }
43
+ export type TTypedSocketRestoreRequestFactory = <T extends plugins.typedrequestInterfaces.ITypedRequest>(methodNameArg: T['method']) => plugins.typedrequest.TypedRequest<T>;
44
+ export interface ITypedSocketRequestContext {
45
+ readonly localData: Readonly<Record<string, unknown>>;
46
+ }
47
+ export declare class TypedSocketConnectionRestoreDeniedError extends Error {
48
+ constructor(messageArg: string);
49
+ }
4
50
  /**
5
51
  * Options for creating a TypedSocket client
6
52
  */
@@ -10,6 +56,16 @@ export interface ITypedSocketClientOptions {
10
56
  initialBackoffMs?: number;
11
57
  maxBackoffMs?: number;
12
58
  abortSignal?: AbortSignal;
59
+ nativeByteCapabilityMode?: TNativeByteCapabilityMode;
60
+ /** Limits may lower, but never raise, TypedSocket package ceilings. */
61
+ limits?: Partial<ITypedSocketClientLimits>;
62
+ /** Restores connection-bound authentication before desired tags are reconciled. */
63
+ restoreConnection?: (contextArg: ITypedSocketConnectionRestoreContext) => void | Promise<void>;
64
+ }
65
+ export interface ITypedSocketServerOptions {
66
+ nativeByteCapabilityMode?: TNativeByteCapabilityMode;
67
+ nativeByteAuthorizationAdapter?: INativeByteAuthorizationAdapter;
68
+ clientTagPolicy?: ITypedSocketClientTagPolicy;
13
69
  }
14
70
  /**
15
71
  * Lifecycle controls for one TypedRequest sent over a TypedSocket.
@@ -20,7 +76,7 @@ export interface ITypedSocketRequestOptions {
20
76
  }
21
77
  export type TTypedSocketServerRouterInput = plugins.typedrequest.TypedRouter | readonly plugins.typedrequest.TypedRouter[];
22
78
  /**
23
- * Wrapper for SmartServe's IWebSocketPeer to provide tag compatibility
79
+ * Typed connection wrapper for one exact SmartServe WebSocket peer.
24
80
  */
25
81
  export interface ISmartServeConnectionWrapper {
26
82
  peer: plugins.IWebSocketPeer;
@@ -60,7 +116,7 @@ export declare class TypedSocket {
60
116
  *
61
117
  * Call attachSmartServe() after constructing the SmartServe transport.
62
118
  */
63
- static createServer(typedRouterOrRoutersArg: TTypedSocketServerRouterInput): TypedSocket;
119
+ static createServer(typedRouterOrRoutersArg: TTypedSocketServerRouterInput, optionsArg?: ITypedSocketServerOptions): TypedSocket;
64
120
  /**
65
121
  * Creates and attaches a TypedSocket server to an existing SmartServe
66
122
  * instance. Prefer createServer() plus attachSmartServe() when transport
@@ -75,24 +131,30 @@ export declare class TypedSocket {
75
131
  * const smartServe = new SmartServe({
76
132
  * port: 3000,
77
133
  * websocket: {
78
- * typedRouter,
79
- * onConnectionOpen: (peer) => peer.tags.add('client')
134
+ * typedRouter
80
135
  * }
81
136
  * });
82
137
  * await smartServe.start();
83
138
  * const typedSocket = TypedSocket.fromSmartServe(smartServe, typedRouter);
139
+ * // Authenticated server handlers assign protected connection metadata with:
140
+ * // typedSocket.setServerTag(peer, 'authenticated', { userId });
84
141
  * ```
85
142
  */
86
- static fromSmartServe(smartServeArg: plugins.SmartServe, typedRouterArg: TTypedSocketServerRouterInput): TypedSocket;
143
+ static fromSmartServe(smartServeArg: plugins.SmartServe, typedRouterArg: TTypedSocketServerRouterInput, optionsArg?: ITypedSocketServerOptions): TypedSocket;
87
144
  /**
88
145
  * Registers built-in TypedHandlers for tag management
89
146
  */
90
- private static registerTagHandlers;
147
+ private static registerProtocolHandlers;
91
148
  readonly side: TTypedSocketSide;
92
149
  readonly typedrouter: plugins.typedrequest.TypedRouter;
150
+ readonly nativeBytes: NativeByteManager;
151
+ readonly webSocketTransportOwner: plugins.IWebSocketTransportOwner;
93
152
  statusSubject: plugins.smartrx.rxjs.Subject<TConnectionStatus>;
94
153
  private connectionStatus;
95
154
  private websocket;
155
+ private connectionGeneration;
156
+ private clientConnectionState;
157
+ private retainedClientCallbacks;
96
158
  private clientOptions;
97
159
  private serverUrl;
98
160
  private retryCount;
@@ -102,14 +164,28 @@ export declare class TypedSocket {
102
164
  private stopListeners;
103
165
  private pendingRequests;
104
166
  private clientTags;
105
- private clientTagMutations;
167
+ private clientTagRevisions;
168
+ private desiredClientTags;
169
+ private clientTagDesiredMutationQueues;
170
+ private clientTagMutationSequence;
171
+ private clientTagMutationTails;
172
+ private retainedClientTagMutations;
173
+ private retainedClientTagMutationsByName;
106
174
  private smartServeRef;
107
175
  private serverTypedRouters;
108
176
  private detachProtocolRouters;
177
+ private detachLegacyVirtualStreamPolicies;
109
178
  private serverStopping;
179
+ private serverLifecycleGeneration;
110
180
  private unsubscribeSmartServeConnectionClose;
181
+ private detachNativeStreamResolvers;
182
+ private detachResponseAuthorityGuards;
111
183
  private pendingServerRequests;
112
- private pendingServerRequestIdsByPeerId;
184
+ private pendingServerRequestIdsByPeer;
185
+ private retainedServerInterests;
186
+ private retainedServerInterestsByPeer;
187
+ private readonly nativeByteAuthorizationAdapter;
188
+ private readonly tagPolicyManager;
113
189
  private constructor();
114
190
  /**
115
191
  * Attaches the SmartServe transport after server router composition.
@@ -119,14 +195,20 @@ export declare class TypedSocket {
119
195
  * Connects the client to the server using native WebSocket
120
196
  */
121
197
  private connect;
198
+ private negotiateClientCapabilities;
199
+ private restoreClientConnection;
122
200
  /**
123
201
  * Converts an HTTP(S) URL to a WebSocket URL
124
202
  */
125
203
  private toWebSocketUrl;
126
- /**
127
- * Handles incoming WebSocket messages
128
- */
204
+ private toRedactedLogEndpoint;
205
+ private enqueueClientTextFrame;
206
+ private drainClientTextFrames;
207
+ private assertClientEnvelope;
129
208
  private handleMessage;
209
+ private sendClientTextEnvelope;
210
+ private isCurrentClientConnection;
211
+ private abortClientConnectionState;
130
212
  /**
131
213
  * Handles WebSocket disconnection
132
214
  */
@@ -158,7 +240,12 @@ export declare class TypedSocket {
158
240
  */
159
241
  private sendRequest;
160
242
  private normalizeRequestTimeout;
243
+ private requireClientOptions;
161
244
  private cancelPendingServerRequestsForPeer;
245
+ private retainServerInterestRegistration;
246
+ private authorizeIncomingServerResponse;
247
+ private isAttachedServerPeer;
248
+ private findServerPeerFromRequest;
162
249
  private sendServerRequest;
163
250
  /**
164
251
  * Creates a TypedRequest for the specified method.
@@ -166,6 +253,11 @@ export declare class TypedSocket {
166
253
  * On servers, sends to the specified target connection.
167
254
  */
168
255
  createTypedRequest<T extends plugins.typedrequestInterfaces.ITypedRequest>(methodName: T['method'], targetConnection?: ISmartServeConnectionWrapper, optionsArg?: ITypedSocketRequestOptions): plugins.typedrequest.TypedRequest<T>;
256
+ /**
257
+ * Creates an exact authorized native-byte receive facade for one server peer.
258
+ * TypedRequest carries its opaque descriptor when the facade enters a DTO.
259
+ */
260
+ createVirtualStream(optionsArg: INativeByteCreateVirtualStreamOptions): plugins.typedrequestInterfaces.INativeByteVirtualStreamReceiver<Uint8Array>;
169
261
  /**
170
262
  * Gets the current connection status
171
263
  */
@@ -174,6 +266,7 @@ export declare class TypedSocket {
174
266
  * Stops the TypedSocket client or cleans up server state
175
267
  */
176
268
  stop(): Promise<void>;
269
+ private releaseServerComposition;
177
270
  /**
178
271
  * Sets a tag on this client connection.
179
272
  * Tags are stored on the server and can be used for filtering.
@@ -190,6 +283,22 @@ export declare class TypedSocket {
190
283
  * @client-only
191
284
  */
192
285
  removeTag(name: string): Promise<void>;
286
+ private retainClientTagMutation;
287
+ private setDesiredClientTag;
288
+ private settleDesiredClientTag;
289
+ private serializeClientTagMutation;
290
+ private submitDesiredClientTag;
291
+ private requireTagMutationSuccess;
292
+ private applyClientTagMutation;
293
+ /**
294
+ * Resolves the exact SmartServe transport peer for one incoming TypedRequest.
295
+ * Server handlers can pass their TypedTools argument without type assertions.
296
+ */
297
+ getServerConnectionForRequest(typedToolsArg: ITypedSocketRequestContext | undefined): ISmartServeConnectionWrapper;
298
+ /** Assigns a protected server-owned tag to one connection. */
299
+ setServerTag(connectionArg: ISmartServeConnectionWrapper | plugins.IWebSocketPeer, nameArg: string, payloadArg?: unknown): void;
300
+ /** Removes a server-owned tag while keeping its name protected from clients. */
301
+ removeServerTag(connectionArg: ISmartServeConnectionWrapper | plugins.IWebSocketPeer, nameArg: string): void;
193
302
  /**
194
303
  * Finds all connections matching the filter function.
195
304
  * @server-only