@api.global/typedsocket 6.0.0 → 6.2.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 (34) 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.js +26 -0
  5. package/dist_ts/{nativebytes.manager.d.ts → classes.nativebytemanager.d.ts} +8 -3
  6. package/dist_ts/classes.nativebytemanager.js +2343 -0
  7. package/dist_ts/{typedsocket.classes.typedsocket.d.ts → classes.typedsocket.d.ts} +21 -21
  8. package/dist_ts/{typedsocket.classes.typedsocket.js → classes.typedsocket.js} +123 -260
  9. package/dist_ts/{typedsocket.tags.d.ts → classes.typedsockettagpolicymanager.d.ts} +9 -2
  10. package/dist_ts/classes.typedsockettagpolicymanager.js +549 -0
  11. package/dist_ts/{nativebytes.constants.js → constants.nativebytes.js} +1 -1
  12. package/dist_ts/{nativebytes.codec.d.ts → helpers.nativebytecodec.d.ts} +1 -1
  13. package/dist_ts/helpers.nativebytecodec.js +328 -0
  14. package/dist_ts/helpers.websocket.d.ts +8 -0
  15. package/dist_ts/helpers.websocket.js +13 -0
  16. package/dist_ts/index.d.ts +9 -8
  17. package/dist_ts/index.js +6 -6
  18. package/dist_ts/interfaces.diagnostics.d.ts +73 -0
  19. package/dist_ts/interfaces.diagnostics.js +2 -0
  20. package/dist_ts/{nativebytes.types.d.ts → interfaces.nativebytes.d.ts} +2 -2
  21. package/dist_ts/interfaces.nativebytes.js +2 -0
  22. package/dist_ts/plugins.js +14 -0
  23. package/package.json +1 -1
  24. package/readme.hints.md +26 -1
  25. package/readme.md +120 -55
  26. package/dist_ts/nativebytes.codec.js +0 -328
  27. package/dist_ts/nativebytes.errors.js +0 -26
  28. package/dist_ts/nativebytes.manager.js +0 -2308
  29. package/dist_ts/nativebytes.types.js +0 -2
  30. package/dist_ts/typedsocket.plugins.js +0 -14
  31. package/dist_ts/typedsocket.tags.js +0 -521
  32. /package/dist_ts/{nativebytes.errors.d.ts → classes.nativebyteerror.d.ts} +0 -0
  33. /package/dist_ts/{nativebytes.constants.d.ts → constants.nativebytes.d.ts} +0 -0
  34. /package/dist_ts/{typedsocket.plugins.d.ts → plugins.d.ts} +0 -0
@@ -3,7 +3,7 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@api.global/typedsocket',
6
- version: '6.0.0',
6
+ version: '6.2.0',
7
7
  description: 'A library for creating typed WebSocket connections, supporting bi-directional communication with type safety.'
8
8
  };
9
9
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSx5QkFBeUI7SUFDL0IsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLCtHQUErRztDQUM3SCxDQUFBIn0=
@@ -0,0 +1,51 @@
1
+ import type { TTypedSocketTagMutationResponse } from './classes.typedsockettagpolicymanager.js';
2
+ import type { ITypedSocketTagMutationDeniedDiagnostic } from './interfaces.diagnostics.js';
3
+ export declare const TYPEDSOCKET_MAX_RETAINED_CLIENT_TAG_MUTATIONS_PER_NAME = 8;
4
+ export declare const TYPEDSOCKET_MAX_RETAINED_CLIENT_TAG_MUTATIONS = 64;
5
+ /**
6
+ * Transport surface the reconciler needs from its owning TypedSocket client.
7
+ * The connection state type stays opaque; the reconciler only compares and
8
+ * forwards it.
9
+ */
10
+ export interface IClientTagTransportAdapter<TConnectionState> {
11
+ isCurrentConnection(stateArg: TConnectionState): boolean;
12
+ getCurrentConnectionState(): TConnectionState | null;
13
+ getConnectionGeneration(stateArg: TConnectionState): number;
14
+ getCurrentGeneration(): number;
15
+ fireSetTag(nameArg: string, payloadArg: unknown): Promise<TTypedSocketTagMutationResponse>;
16
+ fireRemoveTag(nameArg: string): Promise<TTypedSocketTagMutationResponse>;
17
+ emitDiagnostic(eventArg: ITypedSocketTagMutationDeniedDiagnostic): void;
18
+ }
19
+ /**
20
+ * Client-side tag state machine: separates desired tag state (survives
21
+ * transport failure, reconciled on every connection) from acknowledged state
22
+ * (bound to one physical connection generation), serializes mutations per
23
+ * name, and bounds retained mutation work.
24
+ */
25
+ export declare class ClientTagReconciler<TConnectionState> {
26
+ private readonly transport;
27
+ private clientTags;
28
+ private clientTagRevisions;
29
+ private desiredClientTags;
30
+ private clientTagDesiredMutationQueues;
31
+ private clientTagMutationSequence;
32
+ private clientTagMutationTails;
33
+ private retainedClientTagMutations;
34
+ private retainedClientTagMutationsByName;
35
+ constructor(transport: IClientTagTransportAdapter<TConnectionState>);
36
+ setTag(nameArg: string, payloadArg: unknown): Promise<void>;
37
+ removeTag(nameArg: string): Promise<void>;
38
+ /**
39
+ * Re-applies all client tags after a reconnect, since server-side tags are
40
+ * bound to the previous connection.
41
+ */
42
+ reapplyTags(stateArg: TConnectionState | null): Promise<void>;
43
+ private emitDeniedDiagnostic;
44
+ private retainClientTagMutation;
45
+ private setDesiredClientTag;
46
+ private settleDesiredClientTag;
47
+ private serializeClientTagMutation;
48
+ private submitDesiredClientTag;
49
+ private requireTagMutationSuccess;
50
+ private applyClientTagMutation;
51
+ }
@@ -0,0 +1,290 @@
1
+ import { assertBoundedTextIdentifier, createTypedSocketTagPayloadSnapshot, TYPEDSOCKET_MAX_CLIENT_TAG_RETAINED_BYTES_PER_PEER, TYPEDSOCKET_MAX_CLIENT_TAGS_PER_PEER, TYPEDSOCKET_MAX_TAG_NAME_BYTES, TYPEDSOCKET_TAG_DENIAL_CODES, TypedSocketClientTagDeniedError, } from './classes.typedsockettagpolicymanager.js';
2
+ export const TYPEDSOCKET_MAX_RETAINED_CLIENT_TAG_MUTATIONS_PER_NAME = 8;
3
+ export const TYPEDSOCKET_MAX_RETAINED_CLIENT_TAG_MUTATIONS = 64;
4
+ const textEncoder = new TextEncoder();
5
+ /**
6
+ * Client-side tag state machine: separates desired tag state (survives
7
+ * transport failure, reconciled on every connection) from acknowledged state
8
+ * (bound to one physical connection generation), serializes mutations per
9
+ * name, and bounds retained mutation work.
10
+ */
11
+ export class ClientTagReconciler {
12
+ constructor(transport) {
13
+ this.transport = transport;
14
+ // Acknowledged state is diagnostic state for the current server connection.
15
+ this.clientTags = new Map();
16
+ this.clientTagRevisions = new Map();
17
+ // Desired state survives transport failure and is reconciled on every connection.
18
+ this.desiredClientTags = new Map();
19
+ this.clientTagDesiredMutationQueues = new Map();
20
+ this.clientTagMutationSequence = 0;
21
+ this.clientTagMutationTails = new Map();
22
+ this.retainedClientTagMutations = 0;
23
+ this.retainedClientTagMutationsByName = new Map();
24
+ }
25
+ async setTag(nameArg, payloadArg) {
26
+ let releaseMutation;
27
+ try {
28
+ releaseMutation = this.retainClientTagMutation(nameArg);
29
+ const snapshot = createTypedSocketTagPayloadSnapshot(payloadArg);
30
+ const desired = this.setDesiredClientTag(nameArg, 'set', snapshot.payload, snapshot.byteLength);
31
+ return await this.serializeClientTagMutation(nameArg, async () => {
32
+ let applied;
33
+ try {
34
+ applied = await this.submitDesiredClientTag(nameArg, desired);
35
+ }
36
+ catch (errorArg) {
37
+ this.settleDesiredClientTag(nameArg, desired, errorArg instanceof TypedSocketClientTagDeniedError ? 'denied' : 'retained');
38
+ throw errorArg;
39
+ }
40
+ this.settleDesiredClientTag(nameArg, desired, applied ? 'accepted' : 'retained');
41
+ });
42
+ }
43
+ catch (errorArg) {
44
+ this.emitDeniedDiagnostic('set', nameArg, errorArg);
45
+ throw errorArg;
46
+ }
47
+ finally {
48
+ releaseMutation?.();
49
+ }
50
+ }
51
+ async removeTag(nameArg) {
52
+ let releaseMutation;
53
+ try {
54
+ releaseMutation = this.retainClientTagMutation(nameArg);
55
+ const desired = this.setDesiredClientTag(nameArg, 'remove', undefined, 0);
56
+ return await this.serializeClientTagMutation(nameArg, async () => {
57
+ let applied;
58
+ try {
59
+ applied = await this.submitDesiredClientTag(nameArg, desired);
60
+ }
61
+ catch (errorArg) {
62
+ this.settleDesiredClientTag(nameArg, desired, errorArg instanceof TypedSocketClientTagDeniedError ? 'denied' : 'retained');
63
+ throw errorArg;
64
+ }
65
+ this.settleDesiredClientTag(nameArg, desired, applied ? 'accepted' : 'retained');
66
+ });
67
+ }
68
+ catch (errorArg) {
69
+ this.emitDeniedDiagnostic('remove', nameArg, errorArg);
70
+ throw errorArg;
71
+ }
72
+ finally {
73
+ releaseMutation?.();
74
+ }
75
+ }
76
+ /**
77
+ * Re-applies all client tags after a reconnect, since server-side tags are
78
+ * bound to the previous connection.
79
+ */
80
+ async reapplyTags(stateArg) {
81
+ if (!stateArg || !this.transport.isCurrentConnection(stateArg)) {
82
+ throw new Error('TypedSocket has no active connection for tag restoration.');
83
+ }
84
+ this.clientTags.clear();
85
+ this.clientTagRevisions.clear();
86
+ while (this.transport.isCurrentConnection(stateArg)) {
87
+ const snapshot = Array.from(this.desiredClientTags.entries());
88
+ for (const [name, desired] of snapshot) {
89
+ try {
90
+ const applied = await this.submitDesiredClientTag(name, desired, stateArg);
91
+ if (applied
92
+ && desired.operation === 'remove'
93
+ && this.desiredClientTags.get(name)?.sequence === desired.sequence) {
94
+ this.desiredClientTags.delete(name);
95
+ }
96
+ }
97
+ catch (errorArg) {
98
+ if (errorArg instanceof TypedSocketClientTagDeniedError
99
+ && this.desiredClientTags.get(name)?.sequence === desired.sequence) {
100
+ this.desiredClientTags.delete(name);
101
+ }
102
+ this.emitDeniedDiagnostic(desired.operation, name, errorArg);
103
+ throw errorArg;
104
+ }
105
+ }
106
+ const stable = snapshot.length === this.desiredClientTags.size
107
+ && snapshot.every(([name, desired]) => {
108
+ return this.desiredClientTags.get(name)?.sequence === desired.sequence;
109
+ });
110
+ if (stable)
111
+ return;
112
+ }
113
+ throw new Error('TypedSocket connection changed while restoring client tags.');
114
+ }
115
+ emitDeniedDiagnostic(operationArg, nameArg, errorArg) {
116
+ if (!(errorArg instanceof TypedSocketClientTagDeniedError))
117
+ return;
118
+ let name = '';
119
+ try {
120
+ assertBoundedTextIdentifier(nameArg, 'tag name', TYPEDSOCKET_MAX_TAG_NAME_BYTES);
121
+ name = nameArg;
122
+ }
123
+ catch { }
124
+ this.transport.emitDiagnostic({
125
+ kind: 'tagMutationDenied',
126
+ side: 'client',
127
+ operation: operationArg,
128
+ name,
129
+ code: errorArg.code,
130
+ });
131
+ }
132
+ retainClientTagMutation(nameArg) {
133
+ assertBoundedTextIdentifier(nameArg, 'tag name', TYPEDSOCKET_MAX_TAG_NAME_BYTES);
134
+ const retainedForName = this.retainedClientTagMutationsByName.get(nameArg) ?? 0;
135
+ if (retainedForName >= TYPEDSOCKET_MAX_RETAINED_CLIENT_TAG_MUTATIONS_PER_NAME
136
+ || this.retainedClientTagMutations >= TYPEDSOCKET_MAX_RETAINED_CLIENT_TAG_MUTATIONS) {
137
+ throw new TypedSocketClientTagDeniedError('TAG_MUTATION_CAPACITY_EXCEEDED', 'TypedSocket retained client tag mutation capacity exceeded.');
138
+ }
139
+ this.retainedClientTagMutations++;
140
+ this.retainedClientTagMutationsByName.set(nameArg, retainedForName + 1);
141
+ let released = false;
142
+ return () => {
143
+ if (released)
144
+ return;
145
+ released = true;
146
+ this.retainedClientTagMutations--;
147
+ const currentForName = this.retainedClientTagMutationsByName.get(nameArg);
148
+ if (currentForName === undefined || currentForName < 1) {
149
+ throw new Error('TypedSocket client tag mutation accounting underflow.');
150
+ }
151
+ if (currentForName === 1) {
152
+ this.retainedClientTagMutationsByName.delete(nameArg);
153
+ }
154
+ else {
155
+ this.retainedClientTagMutationsByName.set(nameArg, currentForName - 1);
156
+ }
157
+ };
158
+ }
159
+ setDesiredClientTag(nameArg, operationArg, payloadArg, payloadBytesArg) {
160
+ assertBoundedTextIdentifier(nameArg, 'tag name', TYPEDSOCKET_MAX_TAG_NAME_BYTES);
161
+ const retainedBytes = textEncoder.encode(nameArg).byteLength + payloadBytesArg;
162
+ const desired = Object.freeze({
163
+ sequence: ++this.clientTagMutationSequence,
164
+ operation: operationArg,
165
+ payload: operationArg === 'set' ? payloadArg : undefined,
166
+ retainedBytes,
167
+ });
168
+ const alreadyPresent = this.desiredClientTags.has(nameArg);
169
+ if (!alreadyPresent && this.desiredClientTags.size >= TYPEDSOCKET_MAX_CLIENT_TAGS_PER_PEER) {
170
+ throw new TypedSocketClientTagDeniedError('TAG_COUNT_LIMIT_EXCEEDED', 'TypedSocket desired client tag count limit exceeded.');
171
+ }
172
+ let retainedTotal = retainedBytes;
173
+ for (const [name, entry] of this.desiredClientTags) {
174
+ if (name !== nameArg)
175
+ retainedTotal += entry.retainedBytes;
176
+ }
177
+ if (retainedTotal > TYPEDSOCKET_MAX_CLIENT_TAG_RETAINED_BYTES_PER_PEER) {
178
+ throw new TypedSocketClientTagDeniedError('TAG_RETAINED_BYTES_EXCEEDED', 'TypedSocket desired client tag retained-byte limit exceeded.');
179
+ }
180
+ let queue = this.clientTagDesiredMutationQueues.get(nameArg);
181
+ if (!queue) {
182
+ queue = {
183
+ baseline: this.desiredClientTags.get(nameArg),
184
+ pending: [],
185
+ };
186
+ this.clientTagDesiredMutationQueues.set(nameArg, queue);
187
+ }
188
+ queue.pending.push(desired);
189
+ this.desiredClientTags.set(nameArg, desired);
190
+ return desired;
191
+ }
192
+ settleDesiredClientTag(nameArg, desiredArg, outcomeArg) {
193
+ const queue = this.clientTagDesiredMutationQueues.get(nameArg);
194
+ const settled = queue?.pending.shift();
195
+ if (!queue || settled !== desiredArg) {
196
+ throw new Error('TypedSocket desired client tag mutation order changed unexpectedly.');
197
+ }
198
+ if (outcomeArg === 'accepted') {
199
+ queue.baseline = desiredArg.operation === 'set' ? desiredArg : undefined;
200
+ }
201
+ else if (outcomeArg === 'retained') {
202
+ queue.baseline = desiredArg;
203
+ }
204
+ const current = queue.pending.at(-1) ?? queue.baseline;
205
+ if (current)
206
+ this.desiredClientTags.set(nameArg, current);
207
+ else
208
+ this.desiredClientTags.delete(nameArg);
209
+ if (queue.pending.length === 0)
210
+ this.clientTagDesiredMutationQueues.delete(nameArg);
211
+ }
212
+ async serializeClientTagMutation(nameArg, mutationArg) {
213
+ const previous = this.clientTagMutationTails.get(nameArg) ?? Promise.resolve();
214
+ const operation = previous.catch(() => { }).then(mutationArg);
215
+ const tail = operation.then(() => { }, () => { });
216
+ this.clientTagMutationTails.set(nameArg, tail);
217
+ try {
218
+ await operation;
219
+ }
220
+ finally {
221
+ if (this.clientTagMutationTails.get(nameArg) === tail) {
222
+ this.clientTagMutationTails.delete(nameArg);
223
+ }
224
+ }
225
+ }
226
+ async submitDesiredClientTag(nameArg, desiredArg, stateArg = this.transport.getCurrentConnectionState()) {
227
+ if (!stateArg || !this.transport.isCurrentConnection(stateArg)) {
228
+ throw new Error('WebSocket not connected');
229
+ }
230
+ const connectionGeneration = this.transport.getConnectionGeneration(stateArg);
231
+ const response = desiredArg.operation === 'set'
232
+ ? this.requireTagMutationSuccess(await this.transport.fireSetTag(nameArg, desiredArg.payload))
233
+ : this.requireTagMutationSuccess(await this.transport.fireRemoveTag(nameArg));
234
+ const applied = this.applyClientTagMutation(nameArg, desiredArg.payload, response, connectionGeneration, desiredArg.operation);
235
+ return applied;
236
+ }
237
+ requireTagMutationSuccess(responseArg) {
238
+ if (!responseArg || typeof responseArg.success !== 'boolean') {
239
+ throw new TypedSocketClientTagDeniedError('MALFORMED_TAG_RESPONSE', 'TypedSocket server returned a malformed tag mutation response.');
240
+ }
241
+ if (!responseArg.success) {
242
+ // The denial code is server-controlled data: anything outside the
243
+ // package-defined set collapses to MALFORMED_TAG_RESPONSE so no
244
+ // free-form string reaches typed consumers or diagnostics.
245
+ if (typeof responseArg.code !== 'string'
246
+ || typeof responseArg.message !== 'string'
247
+ || !TYPEDSOCKET_TAG_DENIAL_CODES.includes(responseArg.code)) {
248
+ throw new TypedSocketClientTagDeniedError('MALFORMED_TAG_RESPONSE', 'TypedSocket server returned a malformed tag denial response.');
249
+ }
250
+ throw new TypedSocketClientTagDeniedError(responseArg.code, responseArg.message);
251
+ }
252
+ if (typeof responseArg.connectionId !== 'string'
253
+ || responseArg.connectionId.length === 0
254
+ || !Number.isSafeInteger(responseArg.tagRevision)
255
+ || responseArg.tagRevision < 1) {
256
+ throw new TypedSocketClientTagDeniedError('MALFORMED_TAG_RESPONSE', 'TypedSocket server returned malformed tag mutation ordering metadata.');
257
+ }
258
+ return responseArg;
259
+ }
260
+ applyClientTagMutation(nameArg, payloadArg, responseArg, connectionGenerationArg, operationArg) {
261
+ if (connectionGenerationArg !== this.transport.getCurrentGeneration())
262
+ return false;
263
+ const current = this.clientTagRevisions.get(nameArg);
264
+ if (current) {
265
+ if (connectionGenerationArg < current.connectionGeneration)
266
+ return false;
267
+ if (connectionGenerationArg === current.connectionGeneration) {
268
+ if (responseArg.connectionId !== current.connectionId) {
269
+ throw new TypedSocketClientTagDeniedError('MALFORMED_TAG_RESPONSE', 'TypedSocket server changed tag mutation connection identity within one connection generation.');
270
+ }
271
+ if (responseArg.tagRevision <= current.tagRevision)
272
+ return false;
273
+ }
274
+ }
275
+ if (operationArg === 'set') {
276
+ this.clientTagRevisions.set(nameArg, {
277
+ connectionGeneration: connectionGenerationArg,
278
+ connectionId: responseArg.connectionId,
279
+ tagRevision: responseArg.tagRevision,
280
+ });
281
+ this.clientTags.set(nameArg, createTypedSocketTagPayloadSnapshot(payloadArg).payload);
282
+ }
283
+ else {
284
+ this.clientTags.delete(nameArg);
285
+ this.clientTagRevisions.delete(nameArg);
286
+ }
287
+ return true;
288
+ }
289
+ }
290
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5jbGllbnR0YWdyZWNvbmNpbGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5jbGllbnR0YWdyZWNvbmNpbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCwyQkFBMkIsRUFDM0IsbUNBQW1DLEVBQ25DLGtEQUFrRCxFQUNsRCxvQ0FBb0MsRUFDcEMsOEJBQThCLEVBQzlCLDRCQUE0QixFQUM1QiwrQkFBK0IsR0FDaEMsTUFBTSwwQ0FBMEMsQ0FBQztBQU9sRCxNQUFNLENBQUMsTUFBTSxzREFBc0QsR0FBRyxDQUFDLENBQUM7QUFDeEUsTUFBTSxDQUFDLE1BQU0sNkNBQTZDLEdBQUcsRUFBRSxDQUFDO0FBRWhFLE1BQU0sV0FBVyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7QUFtQ3RDOzs7OztHQUtHO0FBQ0gsTUFBTSxPQUFPLG1CQUFtQjtJQVk5QixZQUNtQixTQUF1RDtRQUF2RCxjQUFTLEdBQVQsU0FBUyxDQUE4QztRQVoxRSw0RUFBNEU7UUFDcEUsZUFBVSxHQUFHLElBQUksR0FBRyxFQUFtQixDQUFDO1FBQ3hDLHVCQUFrQixHQUFHLElBQUksR0FBRyxFQUE4QixDQUFDO1FBQ25FLGtGQUFrRjtRQUMxRSxzQkFBaUIsR0FBRyxJQUFJLEdBQUcsRUFBcUMsQ0FBQztRQUNqRSxtQ0FBOEIsR0FBRyxJQUFJLEdBQUcsRUFBMEMsQ0FBQztRQUNuRiw4QkFBeUIsR0FBRyxDQUFDLENBQUM7UUFDOUIsMkJBQXNCLEdBQUcsSUFBSSxHQUFHLEVBQXlCLENBQUM7UUFDMUQsK0JBQTBCLEdBQUcsQ0FBQyxDQUFDO1FBQy9CLHFDQUFnQyxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO0lBSWxFLENBQUM7SUFFRyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQWUsRUFBRSxVQUFtQjtRQUN0RCxJQUFJLGVBQXlDLENBQUM7UUFDOUMsSUFBSSxDQUFDO1lBQ0gsZUFBZSxHQUFHLElBQUks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
@@ -0,0 +1,26 @@
1
+ export class NativeByteError extends Error {
2
+ constructor(messageArg, code, optionsArg) {
3
+ super(messageArg, optionsArg);
4
+ this.code = code;
5
+ this.name = 'NativeByteError';
6
+ }
7
+ }
8
+ export class NativeByteProtocolError extends NativeByteError {
9
+ constructor(messageArg, optionsArg) {
10
+ super(messageArg, 'NATIVE_BYTE_PROTOCOL_ERROR', optionsArg);
11
+ this.name = 'NativeByteProtocolError';
12
+ }
13
+ }
14
+ export class NativeByteCapabilityError extends NativeByteError {
15
+ constructor(messageArg = 'native-byte-v1 is unavailable', optionsArg) {
16
+ super(messageArg, 'NATIVE_BYTE_CAPABILITY_UNAVAILABLE', optionsArg);
17
+ this.name = 'NativeByteCapabilityError';
18
+ }
19
+ }
20
+ export class NativeByteStreamClosedError extends NativeByteError {
21
+ constructor(messageArg = 'Native byte stream is closed', optionsArg) {
22
+ super(messageArg, 'NATIVE_BYTE_STREAM_CLOSED', optionsArg);
23
+ this.name = 'NativeByteStreamClosedError';
24
+ }
25
+ }
26
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5uYXRpdmVieXRlZXJyb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLm5hdGl2ZWJ5dGVlcnJvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLE9BQU8sZUFBZ0IsU0FBUSxLQUFLO0lBQ3hDLFlBQ0UsVUFBa0IsRUFDRixJQUFZLEVBQzVCLFVBQXlCO1FBRXpCLEtBQUssQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFIZCxTQUFJLEdBQUosSUFBSSxDQUFRO1FBSTVCLElBQUksQ0FBQyxJQUFJLEdBQUcsaUJBQWlCLENBQUM7SUFDaEMsQ0FBQztDQUNGO0FBRUQsTUFBTSxPQUFPLHVCQUF3QixTQUFRLGVBQWU7SUFDMUQsWUFBWSxVQUFrQixFQUFFLFVBQXlCO1FBQ3ZELEtBQUssQ0FBQyxVQUFVLEVBQUUsNEJBQTRCLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDNUQsSUFBSSxDQUFDLElBQUksR0FBRyx5QkFBeUIsQ0FBQztJQUN4QyxDQUFDO0NBQ0Y7QUFFRCxNQUFNLE9BQU8seUJBQTBCLFNBQVEsZUFBZTtJQUM1RCxZQUFZLFVBQVUsR0FBRywrQkFBK0IsRUFBRSxVQUF5QjtRQUNqRixLQUFLLENBQUMsVUFBVSxFQUFFLG9DQUFvQyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ3BFLElBQUksQ0FBQyxJQUFJLEdBQUcsMkJBQTJCLENBQUM7SUFDMUMsQ0FBQztDQUNGO0FBRUQsTUFBTSxPQUFPLDJCQUE0QixTQUFRLGVBQWU7SUFDOUQsWUFBWSxVQUFVLEdBQUcsOEJBQThCLEVBQUUsVUFBeUI7UUFDaEYsS0FBSyxDQUFDLFVBQVUsRUFBRSwyQkFBMkIsRUFBRSxVQUFVLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsSUFBSSxHQUFHLDZCQUE2QixDQUFDO0lBQzVDLENBQUM7Q0FDRiJ9
@@ -1,6 +1,7 @@
1
- import * as plugins from './typedsocket.plugins.js';
2
- import { NativeByteStreamClosedError } from './nativebytes.errors.js';
3
- import type { INativeByteCapabilityStatus, INativeByteCreateReceiveGrantOptions, INativeByteDescriptor, INativeByteOpenSenderOptions, INativeByteReceipt, INativeByteReceiveGrant, INativeByteRuntime, INativeByteStats, TNativeByteCapabilityMode, TNativeByteConnectionBinding, TNativeByteRevalidate } from './nativebytes.types.js';
1
+ import * as plugins from './plugins.js';
2
+ import { NativeByteStreamClosedError } from './classes.nativebyteerror.js';
3
+ import type { INativeByteCapabilityStatus, INativeByteCreateReceiveGrantOptions, INativeByteDescriptor, INativeByteOpenSenderOptions, INativeByteReceipt, INativeByteReceiveGrant, INativeByteRuntime, INativeByteStats, TNativeByteCapabilityMode, TNativeByteConnectionBinding, TNativeByteRevalidate } from './interfaces.nativebytes.js';
4
+ import type { TNativeByteDiagnosticEvent } from './interfaces.diagnostics.js';
4
5
  type TNativeStreamTransport = plugins.typedrequestInterfaces.INativeStreamTransport;
5
6
  type TNativeStreamEndpoint = plugins.typedrequestInterfaces.INativeStreamTransportEndpoint;
6
7
  type TSha256Hasher = ReturnType<typeof plugins.smarthash.createSha256Hasher>;
@@ -187,12 +188,15 @@ export interface INativeByteManagerOptions {
187
188
  readonly side: 'client' | 'server';
188
189
  readonly capabilityMode?: TNativeByteCapabilityMode;
189
190
  readonly runtime?: INativeByteRuntime;
191
+ /** Structured close/rejection diagnostics; must not throw, errors are swallowed. */
192
+ readonly onDiagnostic?: (eventArg: TNativeByteDiagnosticEvent) => void;
190
193
  }
191
194
  export declare class NativeByteManager {
192
195
  readonly webSocketTransportOwner: plugins.IWebSocketTransportOwner;
193
196
  private readonly side;
194
197
  private readonly capabilityMode;
195
198
  private readonly runtime;
199
+ private readonly onDiagnostic?;
196
200
  private readonly clientNativeStreamTransport;
197
201
  private readonly serverConnections;
198
202
  private readonly serverSettlementConnections;
@@ -316,6 +320,7 @@ export declare class NativeByteManager {
316
320
  private releaseOutboundQueueBytes;
317
321
  private releaseProducerPayloadAccounting;
318
322
  private removeQueuedFramesForStream;
323
+ private emitDiagnostic;
319
324
  private closeConnection;
320
325
  private failConnection;
321
326
  }