@api.global/typedsocket 5.1.2 → 6.1.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.
Files changed (36) hide show
  1. package/dist_ts/00_commitinfo_data.js +1 -1
  2. package/dist_ts/classes.clienttagreconciler.d.ts +51 -0
  3. package/dist_ts/classes.clienttagreconciler.js +290 -0
  4. package/dist_ts/classes.nativebyteerror.d.ts +13 -0
  5. package/dist_ts/classes.nativebyteerror.js +26 -0
  6. package/dist_ts/classes.nativebytemanager.d.ts +327 -0
  7. package/dist_ts/classes.nativebytemanager.js +2343 -0
  8. package/dist_ts/{typedsocket.classes.typedsocket.d.ts → classes.typedsocket.d.ts} +122 -13
  9. package/dist_ts/classes.typedsocket.js +1733 -0
  10. package/dist_ts/classes.typedsockettagpolicymanager.d.ts +112 -0
  11. package/dist_ts/classes.typedsockettagpolicymanager.js +549 -0
  12. package/dist_ts/constants.nativebytes.d.ts +59 -0
  13. package/dist_ts/constants.nativebytes.js +58 -0
  14. package/dist_ts/helpers.nativebytecodec.d.ts +8 -0
  15. package/dist_ts/helpers.nativebytecodec.js +328 -0
  16. package/dist_ts/helpers.websocket.d.ts +8 -0
  17. package/dist_ts/helpers.websocket.js +13 -0
  18. package/dist_ts/index.d.ts +9 -1
  19. package/dist_ts/index.js +6 -2
  20. package/dist_ts/interfaces.diagnostics.d.ts +73 -0
  21. package/dist_ts/interfaces.diagnostics.js +2 -0
  22. package/dist_ts/interfaces.nativebytes.d.ts +187 -0
  23. package/dist_ts/interfaces.nativebytes.js +2 -0
  24. package/{ts/typedsocket.plugins.ts → dist_ts/plugins.d.ts} +3 -9
  25. package/dist_ts/plugins.js +14 -0
  26. package/{license → license.md} +2 -2
  27. package/package.json +22 -18
  28. package/readme.hints.md +60 -19
  29. package/readme.md +536 -56
  30. package/dist_ts/typedsocket.classes.typedsocket.js +0 -941
  31. package/dist_ts/typedsocket.plugins.d.ts +0 -11
  32. package/dist_ts/typedsocket.plugins.js +0 -13
  33. package/npmextra.json +0 -35
  34. package/ts/00_commitinfo_data.ts +0 -8
  35. package/ts/index.ts +0 -1
  36. package/ts/typedsocket.classes.typedsocket.ts +0 -1156
@@ -0,0 +1,187 @@
1
+ import type * as plugins from './plugins.js';
2
+ import type { NATIVE_BYTE_FRAME_TYPES, NATIVE_BYTE_PROTOCOL } from './constants.nativebytes.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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlcy5uYXRpdmVieXRlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2ludGVyZmFjZXMubmF0aXZlYnl0ZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9
@@ -1,18 +1,12 @@
1
- // @apiglobal scope
2
1
  import * as typedrequest from '@api.global/typedrequest';
3
2
  import * as typedrequestInterfaces from '@api.global/typedrequest-interfaces';
4
-
5
3
  export { typedrequest, typedrequestInterfaces };
6
-
7
- // @pushrocks scope
8
4
  import * as smartdelay from '@push.rocks/smartdelay';
5
+ import * as smarthash from '@push.rocks/smarthash/web';
9
6
  import * as smartjson from '@push.rocks/smartjson';
10
7
  import * as smartpromise from '@push.rocks/smartpromise';
11
8
  import * as smartrx from '@push.rocks/smartrx';
12
9
  import * as smartstring from '@push.rocks/smartstring';
13
10
  import * as smarturl from '@push.rocks/smarturl';
14
-
15
- export { smartdelay, smartjson, smartpromise, smartrx, smartstring, smarturl };
16
-
17
- // SmartServe - required for server-side WebSocket support
18
- export type { SmartServe, IWebSocketPeer } from '@push.rocks/smartserve';
11
+ export { smartdelay, smarthash, smartjson, smartpromise, smartrx, smartstring, smarturl };
12
+ export type { SmartServe, IWebSocketPeer, IWebSocketTransportOwner, TWebSocketOutboundRawFrame, IWebSocketRawFrameSettlement, } from '@push.rocks/smartserve';
@@ -0,0 +1,14 @@
1
+ // @apiglobal scope
2
+ import * as typedrequest from '@api.global/typedrequest';
3
+ import * as typedrequestInterfaces from '@api.global/typedrequest-interfaces';
4
+ export { typedrequest, typedrequestInterfaces };
5
+ // @pushrocks scope
6
+ import * as smartdelay from '@push.rocks/smartdelay';
7
+ import * as smarthash from '@push.rocks/smarthash/web';
8
+ import * as smartjson from '@push.rocks/smartjson';
9
+ import * as smartpromise from '@push.rocks/smartpromise';
10
+ import * as smartrx from '@push.rocks/smartrx';
11
+ import * as smartstring from '@push.rocks/smartstring';
12
+ import * as smarturl from '@push.rocks/smarturl';
13
+ export { smartdelay, smarthash, smartjson, smartpromise, smartrx, smartstring, smarturl };
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsbUJBQW1CO0FBQ25CLE9BQU8sS0FBSyxZQUFZLE1BQU0sMEJBQTBCLENBQUM7QUFDekQsT0FBTyxLQUFLLHNCQUFzQixNQUFNLHFDQUFxQyxDQUFDO0FBRTlFLE9BQU8sRUFBRSxZQUFZLEVBQUUsc0JBQXNCLEVBQUUsQ0FBQztBQUVoRCxtQkFBbUI7QUFDbkIsT0FBTyxLQUFLLFVBQVUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEtBQUssU0FBUyxNQUFNLDJCQUEyQixDQUFDO0FBQ3ZELE9BQU8sS0FBSyxTQUFTLE1BQU0sdUJBQXVCLENBQUM7QUFDbkQsT0FBTyxLQUFLLFlBQVksTUFBTSwwQkFBMEIsQ0FBQztBQUN6RCxPQUFPLEtBQUssT0FBTyxNQUFNLHFCQUFxQixDQUFDO0FBQy9DLE9BQU8sS0FBSyxXQUFXLE1BQU0seUJBQXlCLENBQUM7QUFDdkQsT0FBTyxLQUFLLFFBQVEsTUFBTSxzQkFBc0IsQ0FBQztBQUVqRCxPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLENBQUMifQ==
@@ -1,4 +1,4 @@
1
- Copyright (c) 2020 Lossless GmbH (hello@lossless.com)
1
+ Copyright (c) 2020 Task Venture Capital GmbH (hello@task.vc)
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to deal
@@ -16,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
16
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
17
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
18
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
- SOFTWARE.
19
+ SOFTWARE.
package/package.json CHANGED
@@ -1,12 +1,19 @@
1
1
  {
2
2
  "name": "@api.global/typedsocket",
3
- "version": "5.1.2",
3
+ "version": "6.1.0",
4
4
  "private": false,
5
5
  "description": "A library for creating typed WebSocket connections, supporting bi-directional communication with type safety.",
6
6
  "main": "dist_ts/index.js",
7
7
  "typings": "dist_ts/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist_ts/index.d.ts",
11
+ "import": "./dist_ts/index.js",
12
+ "default": "./dist_ts/index.js"
13
+ }
14
+ },
8
15
  "type": "module",
9
- "author": "Lossless GmbH",
16
+ "author": "Task Venture Capital GmbH",
10
17
  "license": "MIT",
11
18
  "devDependencies": {
12
19
  "@git.zone/tsbuild": "^4.4.2",
@@ -14,13 +21,14 @@
14
21
  "@git.zone/tsrun": "^2.0.6",
15
22
  "@git.zone/tstest": "^3.6.7",
16
23
  "@push.rocks/smartenv": "^6.1.0",
17
- "@push.rocks/smartserve": "^2.6.0",
24
+ "@push.rocks/smartserve": "^4.2.1",
18
25
  "@types/node": "26.1.1"
19
26
  },
20
27
  "dependencies": {
21
- "@api.global/typedrequest": "^3.7.0",
22
- "@api.global/typedrequest-interfaces": "^4.0.0",
28
+ "@api.global/typedrequest": "^5.2.1",
29
+ "@api.global/typedrequest-interfaces": "^5.1.1",
23
30
  "@push.rocks/smartdelay": "^3.1.0",
31
+ "@push.rocks/smarthash": "^3.3.0",
24
32
  "@push.rocks/smartjson": "^6.0.1",
25
33
  "@push.rocks/smartpromise": "^4.2.4",
26
34
  "@push.rocks/smartrx": "^3.0.12",
@@ -28,22 +36,17 @@
28
36
  "@push.rocks/smarturl": "^3.1.0"
29
37
  },
30
38
  "peerDependencies": {
31
- "@push.rocks/smartserve": ">=2.3.0 <4"
39
+ "@push.rocks/smartserve": ">=4.2.1 <5"
32
40
  },
33
41
  "browserslist": [
34
42
  "last 1 chrome versions"
35
43
  ],
36
44
  "files": [
37
- "ts/**/*",
38
- "ts_web/**/*",
39
- "dist/**/*",
40
- "dist_*/**/*",
41
- "dist_ts/**/*",
42
- "dist_ts_web/**/*",
43
- "assets/**/*",
44
- "cli.js",
45
- "npmextra.json",
46
- "readme.md"
45
+ "dist_ts/**/*.js",
46
+ "dist_ts/**/*.d.ts",
47
+ "license.md",
48
+ "readme.md",
49
+ "readme.hints.md"
47
50
  ],
48
51
  "keywords": [
49
52
  "WebSocket",
@@ -55,7 +58,8 @@
55
58
  ],
56
59
  "scripts": {
57
60
  "test": "(tstest test/ --verbose)",
58
- "build": "(tsbuild --web --allowimplicitany --skiplibcheck)",
59
- "buildDocs": "tsdoc"
61
+ "build": "(tsbuild --web --disallowimplicitany)",
62
+ "buildDocs": "tsdoc",
63
+ "verify:package": "tsrun verify.package.ts"
60
64
  }
61
65
  }
package/readme.hints.md CHANGED
@@ -1,21 +1,62 @@
1
1
  # TypedSocket Hints
2
2
 
3
- ## SmartServe Integration (Added v3.1.0)
4
-
5
- TypedSocket now supports SmartServe as an alternative WebSocket backend via `TypedSocket.fromSmartServe()`.
6
-
7
- ### Key Differences from Smartsocket Mode
8
-
9
- 1. **Tag System**: SmartServe uses `Set<string>` for tags, while Smartsocket uses `{id, payload}`. The wrapper stores payloads in `peer.data` with `__typedsocket_tag__` prefix.
10
-
11
- 2. **Request/Response**: Uses TypedRouter's `fireEventInterestMap` for async correlation when sending server-initiated requests.
12
-
13
- 3. **Lifecycle**: SmartServe manages WebSocket lifecycle. `typedSocket.stop()` only clears internal state.
14
-
15
- 4. **eventSubject**: Not fully supported in SmartServe mode - use SmartServe's `onConnectionOpen`/`onConnectionClose` hooks instead.
16
-
17
- ### Files Modified for SmartServe Support
18
-
19
- - `ts/typedsocket.classes.typedsocket.ts` - Main implementation
20
- - `ts/typedsocket.plugins.ts` - Type imports
21
- - `package.json` - Optional peer dependency
3
+ ## TypedSocket 6 Integration
4
+
5
+ TypedSocket 6 requires SmartServe 4.2.1 and TypedRequest 5.2.1. Compose the
6
+ TypedSocket server before constructing SmartServe so `webSocketTransportOwner`
7
+ is selected for the physical peer at upgrade time.
8
+
9
+ ### Authority Rules
10
+
11
+ 1. **Peer identity**: Incoming server handlers call
12
+ `getServerConnectionForRequest(typedTools)` to obtain the exact typed transport
13
+ connection without assertions. Tag validators receive opaque `connectionId`
14
+ and `routingSurfaceId` identities instead of mutable peer/router objects.
15
+
16
+ 2. **Tags**: Client tags are default-deny exact rules. Authentication, roles,
17
+ registration, and reserved names are assigned only with `setServerTag()`.
18
+
19
+ 3. **Bytes**: Generic legacy VirtualStreams are always denied. Exact native-byte
20
+ facades require fixed manifests, principal/revision authority, and durable
21
+ confirmation.
22
+
23
+ 4. **Lifecycle**: Client text work, native frames, callbacks, pending requests,
24
+ tag mutations, and server request interests have fixed resource ceilings and
25
+ generation fencing. SmartServe settlements authorize only the exact frame
26
+ object returned by `pullBinaryFrame()`.
27
+
28
+ 5. **Restoration**: `restoreConnection(context)` runs after capability
29
+ negotiation and before desired tags or `connected`. Use
30
+ `context.createTypedRequest()` for authenticated restoration RPCs; it inherits
31
+ the restoration deadline and abort signal and becomes invalid afterward.
32
+
33
+ ### Diagnostics and Close Codes
34
+
35
+ `diagnosticsSubject` (and `onDiagnostic` on a standalone `NativeByteManager`)
36
+ publishes structured invariant-close, peer-rejection, reconnect, tag-denial,
37
+ and implicit-targeting events. Emission must never disturb transport paths:
38
+ every sink call is try/catch-wrapped.
39
+
40
+ The WebSocket JS `close()` API only permits codes 1000 and 3000-4999. All
41
+ client-initiated invariant closes therefore go through
42
+ `toClientWebSocketCloseCode()` (1009 -> 4009). Calling `close(1008)` on a real
43
+ client WebSocket throws `InvalidAccessError` — under Node/undici that escapes
44
+ `onmessage` as an uncaught exception and kills the process, and inside
45
+ `NativeByteManager`'s try/catch it silently left the socket open. Server-side
46
+ `peer.close()` keeps protocol codes; diagnostics always report the semantic
47
+ protocol code.
48
+
49
+ ### Source Layout
50
+
51
+ Files are named after their main class: `classes.typedsocket.ts`,
52
+ `classes.typedsockettagpolicymanager.ts`, `classes.clienttagreconciler.ts`
53
+ (client desired/acknowledged tag state machine behind a transport adapter),
54
+ `classes.nativebytemanager.ts`, `classes.nativebyteerror.ts`, plus
55
+ `helpers.*`, `interfaces.*`, `constants.*`, and `plugins.ts`.
56
+
57
+ ### Release Artifact
58
+
59
+ Only compiled `dist_ts` JavaScript/declarations, package metadata, documentation,
60
+ and the license are published. `pnpm run verify:package` performs the deterministic
61
+ two-pack entry, hash, metadata, and smoke-import gate (exact artifact count is
62
+ asserted in `verify.package.ts` — update it when adding source files).