@hediet/linkrpc 0.0.1

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 (39) hide show
  1. package/README.md +383 -0
  2. package/dist/chunks/_empty-crypto-Bi0tGx5K.js +8 -0
  3. package/dist/chunks/boundedTrafficSubscription-1L592xc7.js +1126 -0
  4. package/dist/chunks/boundedTrafficSubscription-1L592xc7.js.map +1 -0
  5. package/dist/chunks/hub.interfaces-BzWfsVT2.js +526 -0
  6. package/dist/chunks/hub.interfaces-BzWfsVT2.js.map +1 -0
  7. package/dist/chunks/hubAccess-DwTZPiI8.d.ts +79 -0
  8. package/dist/chunks/hubAccess-DwTZPiI8.d.ts.map +1 -0
  9. package/dist/chunks/hubFacade-CQflVkVC.js +85 -0
  10. package/dist/chunks/hubFacade-CQflVkVC.js.map +1 -0
  11. package/dist/chunks/hubFacade-Dkgw2pTi.d.ts +101 -0
  12. package/dist/chunks/hubFacade-Dkgw2pTi.d.ts.map +1 -0
  13. package/dist/chunks/linkRpcConnection-CtlQmetO.d.ts +3623 -0
  14. package/dist/chunks/linkRpcConnection-CtlQmetO.d.ts.map +1 -0
  15. package/dist/chunks/rolldown-runtime-4LSo1kEK.js +17 -0
  16. package/dist/chunks/src-D3NUIwyo.js +7795 -0
  17. package/dist/chunks/src-D3NUIwyo.js.map +1 -0
  18. package/dist/hub/client/index.d.ts +50 -0
  19. package/dist/hub/client/index.d.ts.map +1 -0
  20. package/dist/hub/client/index.js +97 -0
  21. package/dist/hub/client/index.js.map +1 -0
  22. package/dist/hub/common/index.d.ts +1189 -0
  23. package/dist/hub/common/index.d.ts.map +1 -0
  24. package/dist/hub/common/index.js +267 -0
  25. package/dist/hub/common/index.js.map +1 -0
  26. package/dist/index.d.ts +6 -0
  27. package/dist/index.js +7 -0
  28. package/dist/inspection/index.d.ts +66 -0
  29. package/dist/inspection/index.d.ts.map +1 -0
  30. package/dist/inspection/index.js +6 -0
  31. package/dist/node.d.ts +548 -0
  32. package/dist/node.d.ts.map +1 -0
  33. package/dist/node.js +1087 -0
  34. package/dist/node.js.map +1 -0
  35. package/dist/web.d.ts +44 -0
  36. package/dist/web.d.ts.map +1 -0
  37. package/dist/web.js +58 -0
  38. package/dist/web.js.map +1 -0
  39. package/package.json +59 -0
@@ -0,0 +1,1126 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License. See License.txt in the project root for license information.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { any, array, boolean, enum as enum$1, int, literal, nonnegative, number, object, optional, record, string, union, unknown, void as void$1 } from "zod/mini";
6
+ import { toJSONSchema } from "zod/v4/core";
7
+ //#region src/schema/normalize.ts
8
+ /**
9
+ * Keys that describe structural shape and are part of the decidable subset.
10
+ * Everything else gets stripped during normalization.
11
+ *
12
+ * Note: `not` is intentionally NOT in this list. The special case `{"not":{}}`
13
+ * (i.e. matches-nothing) is mapped to the literal `false` bottom; any other
14
+ * `not` is dropped.
15
+ */
16
+ const KEPT_KEYS = /* @__PURE__ */ new Set([
17
+ "type",
18
+ "format",
19
+ "properties",
20
+ "required",
21
+ "additionalProperties",
22
+ "items",
23
+ "prefixItems",
24
+ "const",
25
+ "enum",
26
+ "anyOf",
27
+ "oneOf",
28
+ "discriminator",
29
+ "$ref",
30
+ "title",
31
+ "description"
32
+ ]);
33
+ /**
34
+ * Normalize raw JSON Schema output (e.g. from `z.toJSONSchema`) into the
35
+ * SvcJsonSchema subset:
36
+ *
37
+ * - drop annotation keys (`examples`, `default`, `$comment`, `readOnly`, ...)
38
+ * - drop out-of-subset refinements (`pattern`, `minimum`, `multipleOf`,
39
+ * `allOf`, `oneOf`, `if/then/else`, `patternProperties`, ...)
40
+ * - empty schema `{}` ⇒ `true` (top)
41
+ * - `{"not":{}}` ⇒ `false` (bottom); any other `not` is stripped
42
+ * - `type:"object"` without `additionalProperties` ⇒ closed (`false`),
43
+ * matching linkrpc's stricter contract
44
+ *
45
+ * The output is canonical: structurally equal inputs produce structurally
46
+ * equal outputs, which is what `computeInterfaceHash` relies on.
47
+ */
48
+ function normalizeJsonSchema(raw) {
49
+ if (raw === true || raw === false) return raw;
50
+ if (raw === null || typeof raw !== "object") throw new Error(`normalizeJsonSchema: expected object, got ${typeof raw}`);
51
+ if (Array.isArray(raw)) throw new Error("normalizeJsonSchema: expected object, got array");
52
+ const r = raw;
53
+ if ("not" in r && isEmptyObject(r["not"])) return false;
54
+ const out = {};
55
+ for (const [k, v] of Object.entries(r)) {
56
+ if (!KEPT_KEYS.has(k)) continue;
57
+ const normalized = normalizeChild(k, v);
58
+ if (normalized === void 0) continue;
59
+ out[k] = normalized;
60
+ }
61
+ if (out["type"] === "object" && !("additionalProperties" in out)) out["additionalProperties"] = false;
62
+ if (Array.isArray(out["oneOf"]) && !("discriminator" in out)) {
63
+ const detected = _detectDiscriminator(out["oneOf"]);
64
+ if (detected !== void 0) out["discriminator"] = detected;
65
+ }
66
+ if ("discriminator" in out && !Array.isArray(out["oneOf"])) delete out["discriminator"];
67
+ if (Object.keys(out).length === 0) return true;
68
+ return out;
69
+ }
70
+ function normalizeChild(key, v) {
71
+ switch (key) {
72
+ case "properties": {
73
+ if (!isPlainObject(v)) return {};
74
+ const out = {};
75
+ for (const [pk, pv] of Object.entries(v)) out[pk] = normalizeJsonSchema(pv);
76
+ return out;
77
+ }
78
+ case "items":
79
+ case "additionalProperties":
80
+ if (v === false) return false;
81
+ return normalizeJsonSchema(v);
82
+ case "prefixItems":
83
+ case "anyOf":
84
+ case "oneOf":
85
+ if (!Array.isArray(v)) return [];
86
+ return v.map((s) => normalizeJsonSchema(s));
87
+ case "discriminator": {
88
+ if (!isPlainObject(v)) return void 0;
89
+ const name = v["propertyName"];
90
+ if (typeof name !== "string" || name.length === 0) return void 0;
91
+ return { propertyName: name };
92
+ }
93
+ case "enum":
94
+ if (!Array.isArray(v)) return [];
95
+ return v.slice();
96
+ case "required":
97
+ if (!Array.isArray(v)) return [];
98
+ return v.slice().sort();
99
+ default: return v;
100
+ }
101
+ }
102
+ function isEmptyObject(v) {
103
+ return isPlainObject(v) && Object.keys(v).length === 0;
104
+ }
105
+ function isPlainObject(v) {
106
+ return v !== null && typeof v === "object" && !Array.isArray(v);
107
+ }
108
+ /**
109
+ * Inspect a `oneOf` branch list and return a `discriminator` hint when
110
+ * every branch is an object schema and there is exactly one property name
111
+ * that appears in every branch with a distinct `const`-valued schema.
112
+ *
113
+ * This is the canonical JSON-Schema-only encoding of a tagged union, and
114
+ * the shape `z.toJSONSchema(z.discriminatedUnion(...))` emits.
115
+ */
116
+ function _detectDiscriminator(branches) {
117
+ if (branches.length < 2) return void 0;
118
+ const branchPropsList = [];
119
+ for (const b of branches) {
120
+ if (b === true || b === false) return void 0;
121
+ if (b.type !== "object") return void 0;
122
+ const props = b.properties;
123
+ if (!props) return void 0;
124
+ branchPropsList.push(props);
125
+ }
126
+ let candidates = _constPropNames(branchPropsList[0]);
127
+ for (let i = 1; i < branchPropsList.length; i++) {
128
+ candidates = candidates.filter((n) => _constPropNames(branchPropsList[i]).includes(n));
129
+ if (candidates.length === 0) return void 0;
130
+ }
131
+ for (const name of candidates) {
132
+ const seen = /* @__PURE__ */ new Set();
133
+ let allDistinct = true;
134
+ for (const props of branchPropsList) {
135
+ const s = props[name];
136
+ const key = JSON.stringify(s.const);
137
+ if (seen.has(key)) {
138
+ allDistinct = false;
139
+ break;
140
+ }
141
+ seen.add(key);
142
+ }
143
+ if (allDistinct) return { propertyName: name };
144
+ }
145
+ }
146
+ function _constPropNames(props) {
147
+ const out = [];
148
+ for (const [k, v] of Object.entries(props)) {
149
+ if (v === true || v === false) continue;
150
+ if ("const" in v) out.push(k);
151
+ }
152
+ return out;
153
+ }
154
+ //#endregion
155
+ //#region src/schema/memberTypes.ts
156
+ var RequestType = class RequestType {
157
+ paramsSchema;
158
+ resultSchema;
159
+ errorSchema;
160
+ docs;
161
+ clientStreamSchema;
162
+ serverStreamSchema;
163
+ kind = "request";
164
+ constructor(paramsSchema, resultSchema, errorSchema, docs = {}, clientStreamSchema, serverStreamSchema) {
165
+ this.paramsSchema = paramsSchema;
166
+ this.resultSchema = resultSchema;
167
+ this.errorSchema = errorSchema;
168
+ this.docs = docs;
169
+ this.clientStreamSchema = clientStreamSchema;
170
+ this.serverStreamSchema = serverStreamSchema;
171
+ }
172
+ /**
173
+ * Return a copy of this request type with stream payload schemas
174
+ * attached. Pass `undefined` for either direction to leave it
175
+ * closed.
176
+ */
177
+ withStream(opts) {
178
+ return new RequestType(this.paramsSchema, this.resultSchema, this.errorSchema, this.docs, opts.client, opts.server);
179
+ }
180
+ };
181
+ var NotificationType = class {
182
+ paramsSchema;
183
+ docs;
184
+ kind = "notification";
185
+ constructor(paramsSchema, docs = {}) {
186
+ this.paramsSchema = paramsSchema;
187
+ this.docs = docs;
188
+ }
189
+ };
190
+ /**
191
+ * Define a request method.
192
+ *
193
+ * @example
194
+ * bar: requestType(z.object({ to: z.string() }), z.string(), {
195
+ * description: "MUST resolve before the next call from the same caller.",
196
+ * })
197
+ */
198
+ function requestType(params, result, docsOrError, maybeDocs) {
199
+ const isErrorSchema = (v) => typeof v === "object" && v !== null && "_zod" in v;
200
+ const error = isErrorSchema(docsOrError) ? docsOrError : void 0;
201
+ const docs = (!isErrorSchema(docsOrError) ? docsOrError : maybeDocs) ?? {};
202
+ return new RequestType(params, result ?? void$1(), error ?? void$1(), docs);
203
+ }
204
+ /**
205
+ * Define a notification method.
206
+ *
207
+ * @example
208
+ * foo: notificationType(z.object({ message: z.string() }))
209
+ */
210
+ function notificationType(params, docs = {}) {
211
+ return new NotificationType(params, docs);
212
+ }
213
+ /** Convert a zod schema to our restricted SvcJsonSchema subset. */
214
+ function zodToSvcJsonSchema(schema, options) {
215
+ const type = schema._zod?.def?.type;
216
+ if (type === "void" || type === "undefined") return true;
217
+ return normalizeZodJsonSchema(toJSONSchema(schema), options);
218
+ }
219
+ function normalizeZodJsonSchema(raw, options) {
220
+ if (!isRecord(raw)) return normalizeJsonSchema(raw);
221
+ const definitions = isRecord(raw.$defs) ? raw.$defs : {};
222
+ const localRefs = collectLocalRefs(raw);
223
+ if (Object.keys(definitions).length === 0 && localRefs.size === 0) return normalizeJsonSchema(raw);
224
+ if (options === void 0) throw new Error("zodToSvcJsonSchema: local references require a component destination");
225
+ const componentNamePrefix = `method=${encodeComponentNamePart(options.methodName)}&schema=${encodeComponentNamePart(options.schemaPosition)}`;
226
+ const definitionComponents = /* @__PURE__ */ new Map();
227
+ for (const definitionName of Object.keys(definitions)) definitionComponents.set(definitionName, `${componentNamePrefix}&def=${encodeComponentNamePart(definitionName)}`);
228
+ const rootComponent = localRefs.has("#") ? `${componentNamePrefix}&root` : void 0;
229
+ const rewrite = (value) => rewriteLocalRefs(value, definitionComponents, rootComponent);
230
+ for (const [definitionName, definition] of Object.entries(definitions)) {
231
+ const componentName = definitionComponents.get(definitionName);
232
+ if (componentName === void 0) throw new Error(`zodToSvcJsonSchema: missing component for "${definitionName}"`);
233
+ addComponent(options.components, componentName, normalizeJsonSchema(rewrite(definition)));
234
+ }
235
+ const root = rewrite(raw);
236
+ if (rootComponent !== void 0) {
237
+ addComponent(options.components, rootComponent, normalizeJsonSchema(root));
238
+ return { $ref: componentRef(rootComponent) };
239
+ }
240
+ return normalizeJsonSchema(root);
241
+ }
242
+ function collectLocalRefs(value, refs = /* @__PURE__ */ new Set()) {
243
+ if (Array.isArray(value)) {
244
+ for (const child of value) collectLocalRefs(child, refs);
245
+ return refs;
246
+ }
247
+ if (!isRecord(value)) return refs;
248
+ if (typeof value.$ref === "string" && value.$ref.startsWith("#")) refs.add(value.$ref);
249
+ for (const child of Object.values(value)) collectLocalRefs(child, refs);
250
+ return refs;
251
+ }
252
+ function rewriteLocalRefs(value, definitionComponents, rootComponent) {
253
+ if (Array.isArray(value)) return value.map((child) => rewriteLocalRefs(child, definitionComponents, rootComponent));
254
+ if (!isRecord(value)) return value;
255
+ const result = {};
256
+ for (const [key, child] of Object.entries(value)) {
257
+ if (key === "$defs") continue;
258
+ if (key === "$ref" && typeof child === "string") result[key] = rewriteLocalRef(child, definitionComponents, rootComponent);
259
+ else result[key] = rewriteLocalRefs(child, definitionComponents, rootComponent);
260
+ }
261
+ return result;
262
+ }
263
+ function rewriteLocalRef(ref, definitionComponents, rootComponent) {
264
+ if (ref === "#") {
265
+ if (rootComponent === void 0) throw new Error("zodToSvcJsonSchema: root reference has no component destination");
266
+ return componentRef(rootComponent);
267
+ }
268
+ if (ref.startsWith("#/$defs/")) {
269
+ const encodedName = ref.slice(8);
270
+ const definitionName = [...definitionComponents.keys()].find((name) => encodeJsonPointerSegment(name) === encodedName);
271
+ const componentName = definitionName === void 0 ? void 0 : definitionComponents.get(definitionName);
272
+ if (componentName === void 0) throw new Error(`zodToSvcJsonSchema: dangling local reference "${ref}"`);
273
+ return componentRef(componentName);
274
+ }
275
+ if (ref.startsWith("#") && !ref.startsWith("#/components/schemas/")) throw new Error(`zodToSvcJsonSchema: unsupported local reference "${ref}"`);
276
+ return ref;
277
+ }
278
+ function addComponent(components, name, schema) {
279
+ if (Object.hasOwn(components, name)) throw new Error(`zodToSvcJsonSchema: duplicate component name "${name}"`);
280
+ components[name] = schema;
281
+ }
282
+ function componentRef(name) {
283
+ return `#/components/schemas/${encodeJsonPointerSegment(name)}`;
284
+ }
285
+ function encodeJsonPointerSegment(value) {
286
+ return value.replace(/~/g, "~0").replace(/\//g, "~1");
287
+ }
288
+ function encodeComponentNamePart(value) {
289
+ return encodeURIComponent(value).replace(/~/g, "%7E");
290
+ }
291
+ function isRecord(value) {
292
+ return value !== null && typeof value === "object" && !Array.isArray(value);
293
+ }
294
+ //#endregion
295
+ //#region src/protocol/jcs.ts
296
+ /**
297
+ * RFC 8785 JSON Canonicalization Scheme (JCS).
298
+ *
299
+ * Used as the byte-deterministic encoding under every linkrpc signature
300
+ * (RPC calls, capabilities, hub-signed previews). Both signer and verifier
301
+ * canonicalize the same value object and obtain byte-identical UTF-8 bytes.
302
+ *
303
+ * Implementation inlined from the `canonicalize` npm package (Apache-2.0,
304
+ * https://github.com/erdtman/canonicalize) so this module stays
305
+ * zero-dependency for browser bundlers that don't resolve transitive
306
+ * npm specifiers (e.g. the in-house app-bundler).
307
+ */
308
+ /** RFC 8785 canonical JSON string for `value`. */
309
+ function jcsCanonicalize(value) {
310
+ const out = _canonicalize(value);
311
+ if (out === void 0) throw new Error("jcsCanonicalize: value is not JSON-representable");
312
+ return out;
313
+ }
314
+ const _encoder = new TextEncoder();
315
+ /** UTF-8 bytes of the RFC 8785 canonical JSON for `value`. The thing actually signed / hashed. */
316
+ function jcsCanonicalizeBytes(value) {
317
+ return _encoder.encode(jcsCanonicalize(value));
318
+ }
319
+ function _canonicalize(object, seen = /* @__PURE__ */ new Set()) {
320
+ if (typeof object === "number" && Number.isNaN(object)) throw new Error("NaN is not allowed");
321
+ if (typeof object === "number" && !Number.isFinite(object)) throw new Error("Infinity is not allowed");
322
+ if (object === null || typeof object !== "object") return JSON.stringify(object);
323
+ const obj = object;
324
+ if (typeof obj.toJSON === "function") {
325
+ if (seen.has(obj)) throw new Error("Circular reference detected");
326
+ seen.add(obj);
327
+ const result = _canonicalize(obj.toJSON(), seen);
328
+ seen.delete(obj);
329
+ return result;
330
+ }
331
+ if (seen.has(obj)) throw new Error("Circular reference detected");
332
+ seen.add(obj);
333
+ let result;
334
+ if (Array.isArray(obj)) result = `[${obj.map((cv) => {
335
+ return _canonicalize(cv === void 0 || typeof cv === "symbol" ? null : cv, seen);
336
+ }).join(",")}]`;
337
+ else {
338
+ const parts = [];
339
+ for (const key of Object.keys(obj).sort()) {
340
+ const v = obj[key];
341
+ if (v === void 0 || typeof v === "symbol") continue;
342
+ parts.push(`${JSON.stringify(key)}:${_canonicalize(v, seen)}`);
343
+ }
344
+ result = `{${parts.join(",")}}`;
345
+ }
346
+ seen.delete(obj);
347
+ return result;
348
+ }
349
+ //#endregion
350
+ //#region src/crypto/sha256.ts
351
+ /**
352
+ * Pure-JS SHA-256 (RFC 6234 / FIPS 180-4). Synchronous, dependency-free,
353
+ * isomorphic. Used internally by linkrpc for content-hashing interface
354
+ * schemas and deriving identity slot names; also surfaced through the
355
+ * `crypto` API as `crypto.sha256`. For signature work we go through the
356
+ * `crypto` module (`./identity/crypto`).
357
+ *
358
+ * Replaces the previous `@noble/hashes/sha2` import so the bundle has
359
+ * no runtime npm dependencies. Trades the well-vetted dep for ~80 lines
360
+ * of straight-line code that has no branching on input contents and is
361
+ * exercised by the existing test vectors plus `sha256.test.ts`.
362
+ */
363
+ const K = new Uint32Array([
364
+ 1116352408,
365
+ 1899447441,
366
+ 3049323471,
367
+ 3921009573,
368
+ 961987163,
369
+ 1508970993,
370
+ 2453635748,
371
+ 2870763221,
372
+ 3624381080,
373
+ 310598401,
374
+ 607225278,
375
+ 1426881987,
376
+ 1925078388,
377
+ 2162078206,
378
+ 2614888103,
379
+ 3248222580,
380
+ 3835390401,
381
+ 4022224774,
382
+ 264347078,
383
+ 604807628,
384
+ 770255983,
385
+ 1249150122,
386
+ 1555081692,
387
+ 1996064986,
388
+ 2554220882,
389
+ 2821834349,
390
+ 2952996808,
391
+ 3210313671,
392
+ 3336571891,
393
+ 3584528711,
394
+ 113926993,
395
+ 338241895,
396
+ 666307205,
397
+ 773529912,
398
+ 1294757372,
399
+ 1396182291,
400
+ 1695183700,
401
+ 1986661051,
402
+ 2177026350,
403
+ 2456956037,
404
+ 2730485921,
405
+ 2820302411,
406
+ 3259730800,
407
+ 3345764771,
408
+ 3516065817,
409
+ 3600352804,
410
+ 4094571909,
411
+ 275423344,
412
+ 430227734,
413
+ 506948616,
414
+ 659060556,
415
+ 883997877,
416
+ 958139571,
417
+ 1322822218,
418
+ 1537002063,
419
+ 1747873779,
420
+ 1955562222,
421
+ 2024104815,
422
+ 2227730452,
423
+ 2361852424,
424
+ 2428436474,
425
+ 2756734187,
426
+ 3204031479,
427
+ 3329325298
428
+ ]);
429
+ function _rotr(x, n) {
430
+ return x >>> n | x << 32 - n;
431
+ }
432
+ function sha256(data) {
433
+ const inputLen = data.length;
434
+ const bitLen = inputLen * 8;
435
+ const paddedLen = inputLen + 9 + 63 & -64;
436
+ const padded = new Uint8Array(paddedLen);
437
+ padded.set(data);
438
+ padded[inputLen] = 128;
439
+ const view = new DataView(padded.buffer);
440
+ view.setUint32(paddedLen - 8, Math.floor(bitLen / 4294967296), false);
441
+ view.setUint32(paddedLen - 4, bitLen >>> 0, false);
442
+ const H = new Uint32Array([
443
+ 1779033703,
444
+ 3144134277,
445
+ 1013904242,
446
+ 2773480762,
447
+ 1359893119,
448
+ 2600822924,
449
+ 528734635,
450
+ 1541459225
451
+ ]);
452
+ const W = /* @__PURE__ */ new Uint32Array(64);
453
+ for (let block = 0; block < paddedLen; block += 64) {
454
+ for (let t = 0; t < 16; t++) W[t] = view.getUint32(block + t * 4, false);
455
+ for (let t = 16; t < 64; t++) {
456
+ const w15 = W[t - 15];
457
+ const w2 = W[t - 2];
458
+ const s0 = _rotr(w15, 7) ^ _rotr(w15, 18) ^ w15 >>> 3;
459
+ const s1 = _rotr(w2, 17) ^ _rotr(w2, 19) ^ w2 >>> 10;
460
+ W[t] = W[t - 16] + s0 + W[t - 7] + s1 >>> 0;
461
+ }
462
+ let a = H[0], b = H[1], c = H[2], d = H[3];
463
+ let e = H[4], f = H[5], g = H[6], h = H[7];
464
+ for (let t = 0; t < 64; t++) {
465
+ const S1 = _rotr(e, 6) ^ _rotr(e, 11) ^ _rotr(e, 25);
466
+ const ch = e & f ^ ~e & g;
467
+ const temp1 = h + S1 + ch + K[t] + W[t] >>> 0;
468
+ const temp2 = (_rotr(a, 2) ^ _rotr(a, 13) ^ _rotr(a, 22)) + (a & b ^ a & c ^ b & c) >>> 0;
469
+ h = g;
470
+ g = f;
471
+ f = e;
472
+ e = d + temp1 >>> 0;
473
+ d = c;
474
+ c = b;
475
+ b = a;
476
+ a = temp1 + temp2 >>> 0;
477
+ }
478
+ H[0] = H[0] + a >>> 0;
479
+ H[1] = H[1] + b >>> 0;
480
+ H[2] = H[2] + c >>> 0;
481
+ H[3] = H[3] + d >>> 0;
482
+ H[4] = H[4] + e >>> 0;
483
+ H[5] = H[5] + f >>> 0;
484
+ H[6] = H[6] + g >>> 0;
485
+ H[7] = H[7] + h >>> 0;
486
+ }
487
+ const out = /* @__PURE__ */ new Uint8Array(32);
488
+ const outView = new DataView(out.buffer);
489
+ for (let i = 0; i < 8; i++) outView.setUint32(i * 4, H[i], false);
490
+ return out;
491
+ }
492
+ //#endregion
493
+ //#region src/schema/hash.ts
494
+ const methodSchemaFields = [
495
+ "params",
496
+ "result",
497
+ "clientStream",
498
+ "serverStream"
499
+ ];
500
+ /**
501
+ * Compute the interface hash: SHA-256 of the canonicalized schema, truncated
502
+ * to 16 hex chars (64 bits of collision budget per id).
503
+ *
504
+ * Canonicalization strips the schema down to its **normative wire-contract
505
+ * projection** before hashing, so a single interface document can carry richer
506
+ * non-normative material (codegen hints, safety expressions, notes) without
507
+ * changing identity:
508
+ *
509
+ * 1. Normalize every JSON-Schema position (`params`, `result`, streams, and
510
+ * `components.schemas`) onto the decidable linkrpc subset.
511
+ * 2. Strip every `comment` field (non-normative — must not affect identity).
512
+ * `description` is NORMATIVE and kept in the hash.
513
+ * 3. Strip every **specification-extension** field — any object key whose name
514
+ * begins with `x-` — at every level of the document (see
515
+ * {@link EXTENSION_PREFIX}). This is the minimal, explicit "one document,
516
+ * two views" mechanism: the stored document keeps the rich `x-…`
517
+ * expressions; identity hashes only the simple contract. It mirrors
518
+ * OpenRPC/OpenAPI specification extensions (this schema format is a subset
519
+ * of OpenRPC 1.x). Editing an `x-…` value never changes the hash; changing
520
+ * a wire field (`params`, `result`, member names, `type`, `required`,
521
+ * `description`, `annotations`, …) does.
522
+ * 4. Omit the top-level `hash` field itself.
523
+ * 5. RFC 8785 JCS encode (recursive key sort, no whitespace) via {@link jcsCanonicalize}.
524
+ *
525
+ * Because no interface schema uses `x-…` keys today, this preserves every
526
+ * existing hash: stripping a set of keys that are always absent is a no-op.
527
+ *
528
+ * > Reservation. `x-…` is reserved for non-normative extensions at every level.
529
+ * > Member names cannot collide (they are alphanumeric per chapter 01 §2), and
530
+ * > object property names in the JSON Schema subset MUST NOT begin with `x-`.
531
+ */
532
+ function computeInterfaceHash(schema) {
533
+ const json = jcsCanonicalize(stripNonNormative(normalizeSchemaPositions(schema), true));
534
+ const digest = sha256(new TextEncoder().encode(json));
535
+ return Array.from(digest.subarray(0, 8), (b) => b.toString(16).padStart(2, "0")).join("");
536
+ }
537
+ function normalizeSchemaPositions(schema) {
538
+ const methods = Object.fromEntries(Object.entries(schema.methods).map(([name, method]) => {
539
+ const normalized = { ...method };
540
+ for (const field of methodSchemaFields) {
541
+ const value = normalized[field];
542
+ if (value !== void 0) normalized[field] = normalizeJsonSchema(value);
543
+ }
544
+ return [name, normalized];
545
+ }));
546
+ const componentSchemas = schema.components?.schemas;
547
+ const components = componentSchemas === void 0 ? schema.components : {
548
+ ...schema.components,
549
+ schemas: Object.fromEntries(Object.entries(componentSchemas).map(([name, value]) => [name, normalizeJsonSchema(value)]))
550
+ };
551
+ return {
552
+ ...schema,
553
+ methods,
554
+ ...components === void 0 ? {} : { components }
555
+ };
556
+ }
557
+ /**
558
+ * Prefix marking a non-normative **specification-extension** key. Any object
559
+ * key beginning with this prefix is stripped before hashing (at every level),
560
+ * exactly like `comment`. Reserved for rich, identity-neutral material such as
561
+ * codegen directives, richer validation/safety expressions, or tooling hints.
562
+ */
563
+ const EXTENSION_PREFIX = "x-";
564
+ /** True for a key that must not contribute to the interface hash. */
565
+ function isNonNormativeKey(key, isRoot) {
566
+ return key === "comment" || key.startsWith("x-") || isRoot && key === "hash";
567
+ }
568
+ function stripNonNormative(value, isRoot = false) {
569
+ if (value === null || typeof value !== "object") return value;
570
+ if (Array.isArray(value)) return value.map((v) => stripNonNormative(v));
571
+ const out = {};
572
+ for (const k of Object.keys(value)) {
573
+ if (isNonNormativeKey(k, isRoot)) continue;
574
+ const v = value[k];
575
+ if (v === void 0) continue;
576
+ out[k] = stripNonNormative(v);
577
+ }
578
+ return out;
579
+ }
580
+ //#endregion
581
+ //#region src/connection/interfaceDefinition.ts
582
+ const interfaceDefinitionState = /* @__PURE__ */ new WeakMap();
583
+ var InterfaceDefinition = class {
584
+ info;
585
+ members;
586
+ /** Typed wire references for capability and access-request construction. */
587
+ ref;
588
+ constructor(info, members, opts = {}) {
589
+ this.info = info;
590
+ this.members = members;
591
+ interfaceDefinitionState.set(this, {
592
+ frozenSchema: opts.frozenSchema,
593
+ schemaCache: void 0,
594
+ hashCache: void 0
595
+ });
596
+ this.ref = Object.fromEntries(Object.keys(members).map((member) => [member, {
597
+ interfaceId: this.info.id,
598
+ interfaceHash: this.schemaHash,
599
+ member
600
+ }]));
601
+ if (info.hash !== void 0 && this.schemaHash !== info.hash) throw new Error(`Interface hash mismatch for "${info.id}": expected "${info.hash}", got "${this.schemaHash}". The interface's wire contract changed — update the pinned hash to "${this.schemaHash}" after reviewing the change.`);
602
+ }
603
+ /** Content hash of this interface (see `computeInterfaceHash`). */
604
+ get schemaHash() {
605
+ const state = interfaceDefinitionState.get(this);
606
+ if (state.hashCache === void 0) state.hashCache = computeInterfaceHash(state.frozenSchema ?? buildSchema(this.info, this.members, ""));
607
+ return state.hashCache;
608
+ }
609
+ /** Lower the definition to a wire-format `LinkRpcInterfaceSchema`, hash filled in. */
610
+ toSchema() {
611
+ const state = interfaceDefinitionState.get(this);
612
+ if (state.schemaCache === void 0) state.schemaCache = state.frozenSchema !== void 0 ? {
613
+ ...state.frozenSchema,
614
+ hash: this.schemaHash
615
+ } : buildSchema(this.info, this.members, this.schemaHash);
616
+ return state.schemaCache;
617
+ }
618
+ };
619
+ function buildSchema(info, members, hash) {
620
+ const methods = {};
621
+ const components = {};
622
+ for (const [name, member] of Object.entries(members)) methods[name] = toMethodSchema(name, member, components);
623
+ const schema = {
624
+ id: info.id,
625
+ hash,
626
+ methods
627
+ };
628
+ if (Object.keys(components).length > 0) schema.components = { schemas: components };
629
+ if (info.description !== void 0) schema.description = info.description;
630
+ if (info.comment !== void 0) schema.comment = info.comment;
631
+ return schema;
632
+ }
633
+ function toMethodSchema(name, member, components) {
634
+ const docs = member.docs;
635
+ if (member.kind === "request") {
636
+ const m = {
637
+ params: convertMemberSchema(name, "params", member.paramsSchema, components),
638
+ result: convertMemberSchema(name, "result", member.resultSchema, components)
639
+ };
640
+ if (member.clientStreamSchema !== void 0) m.clientStream = convertMemberSchema(name, "clientStream", member.clientStreamSchema, components);
641
+ if (member.serverStreamSchema !== void 0) m.serverStream = convertMemberSchema(name, "serverStream", member.serverStreamSchema, components);
642
+ if (docs.description !== void 0) m.description = docs.description;
643
+ if (docs.comment !== void 0) m.comment = docs.comment;
644
+ if (docs.annotations !== void 0) m.annotations = docs.annotations;
645
+ return m;
646
+ }
647
+ const m = { params: convertMemberSchema(name, "params", member.paramsSchema, components) };
648
+ if (docs.description !== void 0) m.description = docs.description;
649
+ if (docs.comment !== void 0) m.comment = docs.comment;
650
+ if (docs.annotations !== void 0) m.annotations = docs.annotations;
651
+ return m;
652
+ }
653
+ function convertMemberSchema(methodName, position, schema, components) {
654
+ return zodToSvcJsonSchema(schema, {
655
+ methodName,
656
+ schemaPosition: position,
657
+ components
658
+ });
659
+ }
660
+ /**
661
+ * Convenient builder for an interface definition. Tracks TypeScript types
662
+ * through `requestType` / `notificationType` so client and server code can
663
+ * derive their shapes from the definition.
664
+ *
665
+ * @example
666
+ * const myInterface = defineInterface(
667
+ * { id: "de.hediet.notification-target" },
668
+ * {
669
+ * send: requestType(z.object({ to: z.string() }), z.string()),
670
+ * notify: notificationType(z.object({ message: z.string() })),
671
+ * },
672
+ * );
673
+ */
674
+ function defineInterface(info, members) {
675
+ return new InterfaceDefinition(info, members);
676
+ }
677
+ /**
678
+ * Build a runtime {@link InterfaceDefinition} from a previously-published
679
+ * {@link LinkRpcInterfaceSchema} — typically one received over the wire (e.g.
680
+ * from `hubrpc.schemas::get`) or generated at runtime by tooling that does
681
+ * not have the original zod sources at hand (codegen, faker / mock
682
+ * services, dynamic gateways).
683
+ *
684
+ * The original schema is kept verbatim: `toSchema()` returns it (with
685
+ * `hash` overlaid) and `schemaHash` is computed from it, so reflection
686
+ * consumers see the real wire contract. Member-level params / results /
687
+ * streams use `z.any()` because no zod source is available — call-site
688
+ * validation is therefore a no-op and the caller is responsible for
689
+ * shape-checking inputs and outputs.
690
+ *
691
+ * Methods with no `result` descriptor become notifications; methods with
692
+ * `clientStream` / `serverStream` get pass-through stream payload
693
+ * schemas attached.
694
+ */
695
+ function interfaceFromSchema(schema) {
696
+ const members = {};
697
+ for (const [name, method] of Object.entries(schema.methods)) {
698
+ if (method.result === void 0) {
699
+ members[name] = new NotificationType(any());
700
+ continue;
701
+ }
702
+ const base = new RequestType(any(), any(), void$1());
703
+ members[name] = method.clientStream !== void 0 || method.serverStream !== void 0 ? base.withStream({
704
+ client: method.clientStream !== void 0 ? any() : void 0,
705
+ server: method.serverStream !== void 0 ? any() : void 0
706
+ }) : base;
707
+ }
708
+ const info = { id: schema.id };
709
+ if (schema.description !== void 0) info.description = schema.description;
710
+ if (schema.comment !== void 0) info.comment = schema.comment;
711
+ return new InterfaceDefinition(info, members, { frozenSchema: schema });
712
+ }
713
+ //#endregion
714
+ //#region src/inspection/inspection.interfaces.ts
715
+ const zTopologyPort = object({
716
+ portId: string(),
717
+ label: optional(string())
718
+ });
719
+ const zParticipantDescriptor = object({
720
+ type: optional(string()),
721
+ label: optional(string()),
722
+ processId: optional(number()),
723
+ processType: optional(string()),
724
+ nodeStatusServiceId: optional(string()),
725
+ metadata: optional(record(string(), union([
726
+ string(),
727
+ number(),
728
+ boolean()
729
+ ])))
730
+ });
731
+ const zParticipantDescriptorSource = object({
732
+ source: enum$1(["self", "attacher"]),
733
+ descriptor: zParticipantDescriptor
734
+ });
735
+ const zTopologyNode = object({
736
+ nodeId: string(),
737
+ kind: optional(enum$1(["endpoint", "hub"])),
738
+ label: optional(string()),
739
+ descriptors: optional(array(zParticipantDescriptorSource)),
740
+ ports: array(zTopologyPort)
741
+ });
742
+ const zTopologyLinkEndpoint = object({
743
+ nodeId: string(),
744
+ portId: string()
745
+ });
746
+ const zTopologyTransportEndpoint = object({
747
+ address: optional(string()),
748
+ port: optional(number().check(int(), nonnegative()))
749
+ });
750
+ /**
751
+ * Transport details as observed at a topology link. `local` corresponds to the
752
+ * link's `from` endpoint and `remote` to its `to` endpoint.
753
+ */
754
+ const zTopologyTransportInfo = object({
755
+ type: string(),
756
+ local: optional(zTopologyTransportEndpoint),
757
+ remote: optional(zTopologyTransportEndpoint),
758
+ path: optional(string()),
759
+ metadata: optional(record(string(), union([
760
+ string(),
761
+ number(),
762
+ boolean()
763
+ ])))
764
+ });
765
+ const zTopologyLink = object({
766
+ from: zTopologyLinkEndpoint,
767
+ to: zTopologyLinkEndpoint,
768
+ label: optional(string()),
769
+ peerState: optional(enum$1([
770
+ "identified",
771
+ "pending",
772
+ "unsupported",
773
+ "error"
774
+ ])),
775
+ transport: optional(zTopologyTransportInfo)
776
+ });
777
+ const zRouteClaim = object({
778
+ serviceId: string(),
779
+ nodeId: string(),
780
+ portId: string(),
781
+ match: enum$1(["exact", "prefix"])
782
+ });
783
+ const zTopologyGraph = object({
784
+ observerServiceId: string(),
785
+ entryNodeId: string(),
786
+ nodes: array(zTopologyNode),
787
+ links: array(zTopologyLink),
788
+ routes: array(zRouteClaim)
789
+ });
790
+ const topologyInterface = defineInterface({
791
+ id: "hubrpc.topology",
792
+ description: "Inspect the transport graph visible from a service. A watch emits invalidation ticks; consumers re-fetch getGraph after each tick."
793
+ }, {
794
+ getGraph: requestType(object({}), zTopologyGraph).withStream({ client: object({}) }),
795
+ watchGraph: requestType(object({}), object({})).withStream({ server: object({}) })
796
+ });
797
+ const zTrafficTransitEndpoint = object({
798
+ edgeId: string(),
799
+ portId: string(),
800
+ requestId: optional(union([number(), string()]))
801
+ });
802
+ const zTrafficTransitEvent = object({
803
+ type: literal("transit"),
804
+ timeMs: number(),
805
+ nodeId: string(),
806
+ in: optional(zTrafficTransitEndpoint),
807
+ out: optional(zTrafficTransitEndpoint),
808
+ disposition: enum$1([
809
+ "forwarded",
810
+ "consumed",
811
+ "dropped",
812
+ "unroutable"
813
+ ]),
814
+ kind: enum$1([
815
+ "request",
816
+ "notification",
817
+ "response",
818
+ "stream"
819
+ ]),
820
+ method: optional(string()),
821
+ params: optional(unknown()),
822
+ result: optional(unknown()),
823
+ error: optional(object({
824
+ code: number(),
825
+ message: string(),
826
+ data: optional(unknown())
827
+ }))
828
+ });
829
+ const zTrafficOverflowEvent = object({
830
+ type: literal("overflow"),
831
+ dropped: number().check(int(), nonnegative())
832
+ });
833
+ const zTrafficEvent = union([zTrafficTransitEvent, zTrafficOverflowEvent]);
834
+ const zTrafficWatchResult = object({
835
+ delivered: number().check(int(), nonnegative()),
836
+ dropped: number().check(int(), nonnegative())
837
+ });
838
+ const zTrafficWatchParams = object({
839
+ methodPrefix: optional(string()),
840
+ trafficIgnoreKey: optional(string()),
841
+ focusRequest: optional(object({
842
+ portId: string(),
843
+ requestId: union([number(), string()])
844
+ }))
845
+ });
846
+ const zTrafficWatchWithPayloadsParams = object({
847
+ methodPrefix: optional(string()),
848
+ trafficIgnoreKey: optional(string()),
849
+ focusRequest: optional(object({
850
+ portId: string(),
851
+ requestId: union([number(), string()])
852
+ })),
853
+ maxPayloadBytes: number().check(int(), nonnegative())
854
+ });
855
+ /**
856
+ * Observe raw message transits at the node hosting the addressed service.
857
+ * Consumers may correlate adjacent transits by shared `(portId, requestId)`.
858
+ */
859
+ const trafficInterface = defineInterface({
860
+ id: "hubrpc.traffic",
861
+ description: "Stream raw message transits for the entire node hosting the addressed service. Payload-free and explicitly payload-bearing variants keep disclosure opt-in."
862
+ }, {
863
+ watch: requestType(zTrafficWatchParams, zTrafficWatchResult).withStream({ server: zTrafficEvent }),
864
+ watchWithPayloads: requestType(zTrafficWatchWithPayloadsParams, zTrafficWatchResult).withStream({ server: zTrafficEvent })
865
+ });
866
+ //#endregion
867
+ //#region src/inspection/node.interfaces.ts
868
+ const zNodeInfo = object({
869
+ /**
870
+ * Random identity of this connection's node. It is a topology-correlation
871
+ * label only and must not be used for authentication or authorization.
872
+ */
873
+ nodeId: string(),
874
+ /** Random identity of this connection's port on its node. */
875
+ portId: string(),
876
+ /** Optional diagnostic descriptors; never used for authorization. */
877
+ descriptors: optional(array(zParticipantDescriptorSource))
878
+ });
879
+ /**
880
+ * Minimal root service for aligning the independently observed topologies at
881
+ * both ends of a connection.
882
+ */
883
+ const nodeInterface = defineInterface({
884
+ id: "hubrpc.node",
885
+ description: "Topology bootstrap: identify the node and port at this end of the direct connection."
886
+ }, { getNodeId: requestType(object({}), zNodeInfo) });
887
+ //#endregion
888
+ //#region src/inspection/trafficFlowFilter.ts
889
+ var TrafficFlowFilter = class {
890
+ _focused;
891
+ constructor(options) {
892
+ this._focused = options.focus !== void 0 ? new CorrelatedFlow([options.focus]) : void 0;
893
+ }
894
+ shouldInclude(transit) {
895
+ return this._focused?.accept(transit).matches ?? true;
896
+ }
897
+ };
898
+ var TrafficWatchFlowTracker = class {
899
+ _active = /* @__PURE__ */ new Set();
900
+ _unclaimed = /* @__PURE__ */ new Map();
901
+ accept(transit) {
902
+ if (transit.kind === "request" && isTrafficWatchMethod(transit.method)) {
903
+ const trafficIgnoreKey = readTrafficIgnoreKey(transit.params);
904
+ let flow = this._findFlow(transit);
905
+ if (flow === void 0) {
906
+ flow = new CorrelatedFlow(requestRefsOf(transit), completionRefOf(transit));
907
+ if (!isTerminal(transit)) this._active.add(flow);
908
+ } else flow.accept(transit);
909
+ if (isTerminal(transit)) {
910
+ this._removeFlow(flow);
911
+ return true;
912
+ }
913
+ if (trafficIgnoreKey !== void 0) this._unclaimed.set(trafficIgnoreKey, flow);
914
+ return true;
915
+ }
916
+ for (const flow of this._active) {
917
+ const match = flow.accept(transit);
918
+ if (!match.matches) continue;
919
+ if (match.completed) this._removeFlow(flow);
920
+ return true;
921
+ }
922
+ return false;
923
+ }
924
+ _findFlow(transit) {
925
+ for (const flow of this._active) if (flow.matches(transit)) return flow;
926
+ }
927
+ _removeFlow(flow) {
928
+ this._active.delete(flow);
929
+ for (const [key, pending] of this._unclaimed) if (pending === flow) this._unclaimed.delete(key);
930
+ }
931
+ claim(trafficIgnoreKey) {
932
+ return this._unclaimed.delete(trafficIgnoreKey);
933
+ }
934
+ clear() {
935
+ this._active.clear();
936
+ this._unclaimed.clear();
937
+ }
938
+ };
939
+ var CorrelatedFlow = class {
940
+ _endpoints = /* @__PURE__ */ new Set();
941
+ _completionEndpoint;
942
+ constructor(endpoints, completionEndpoint = endpoints[0]) {
943
+ for (const endpoint of endpoints) this._endpoints.add(endpointKey(endpoint));
944
+ this._completionEndpoint = completionEndpoint === void 0 ? void 0 : endpointKey(completionEndpoint);
945
+ }
946
+ matches(transit) {
947
+ return requestRefsOf(transit).some((endpoint) => this._endpoints.has(endpointKey(endpoint)));
948
+ }
949
+ accept(transit) {
950
+ const endpoints = requestRefsOf(transit);
951
+ if (!this.matches(transit)) return {
952
+ matches: false,
953
+ completed: false
954
+ };
955
+ for (const endpoint of endpoints) this._endpoints.add(endpointKey(endpoint));
956
+ const completed = transit.kind === "response" && (isTerminal(transit) || this._completionEndpoint !== void 0 && endpoints.some((endpoint) => endpointKey(endpoint) === this._completionEndpoint));
957
+ if (completed) this._endpoints.clear();
958
+ return {
959
+ matches: true,
960
+ completed
961
+ };
962
+ }
963
+ };
964
+ function isTerminal(transit) {
965
+ return transit.disposition === "dropped" || transit.disposition === "unroutable";
966
+ }
967
+ function requestRefsOf(transit) {
968
+ const result = [];
969
+ if (transit.in?.requestId !== void 0) result.push(requestRef(transit.in));
970
+ if (transit.out?.requestId !== void 0) result.push(requestRef(transit.out));
971
+ return result;
972
+ }
973
+ function requestRef(endpoint) {
974
+ return {
975
+ portId: endpoint.portId,
976
+ requestId: endpoint.requestId
977
+ };
978
+ }
979
+ function completionRefOf(transit) {
980
+ if (transit.in?.requestId !== void 0) return requestRef(transit.in);
981
+ if (transit.out?.requestId !== void 0) return requestRef(transit.out);
982
+ }
983
+ function endpointKey(endpoint) {
984
+ return JSON.stringify([
985
+ endpoint.portId,
986
+ typeof endpoint.requestId,
987
+ endpoint.requestId
988
+ ]);
989
+ }
990
+ function isTrafficWatchMethod(method) {
991
+ return method?.endsWith("::hubrpc.traffic::watch") === true || method?.endsWith("::hubrpc.traffic::watchWithPayloads") === true || method === "hubrpc.traffic::watch" || method === "hubrpc.traffic::watchWithPayloads";
992
+ }
993
+ function readTrafficIgnoreKey(params) {
994
+ if (params === null || Array.isArray(params) || typeof params !== "object" || !("trafficIgnoreKey" in params)) return;
995
+ const value = params.trafficIgnoreKey;
996
+ return typeof value === "string" ? value : void 0;
997
+ }
998
+ //#endregion
999
+ //#region src/inspection/boundedTrafficSubscription.ts
1000
+ const DEFAULT_QUEUE_LIMIT = 256;
1001
+ /**
1002
+ * Applies per-subscriber filtering and payload policy while isolating traffic
1003
+ * producers from slow or failed stream consumers.
1004
+ */
1005
+ var BoundedTrafficSubscription = class {
1006
+ _options;
1007
+ _send;
1008
+ _onDispose;
1009
+ _queueLimit;
1010
+ _queue = [];
1011
+ _active = true;
1012
+ _pumping = false;
1013
+ _overflowPending = 0;
1014
+ _delivered = 0;
1015
+ _dropped = 0;
1016
+ _resolveClosed;
1017
+ _filter;
1018
+ closed;
1019
+ constructor(_options, _send, _onDispose, _queueLimit = DEFAULT_QUEUE_LIMIT) {
1020
+ this._options = _options;
1021
+ this._send = _send;
1022
+ this._onDispose = _onDispose;
1023
+ this._queueLimit = _queueLimit;
1024
+ let resolve;
1025
+ this.closed = new Promise((r) => resolve = r);
1026
+ this._resolveClosed = resolve;
1027
+ this._filter = new TrafficFlowFilter({ focus: _options.focusRequest });
1028
+ }
1029
+ enqueue(transit) {
1030
+ if (!this._active) return;
1031
+ if (!this._filter.shouldInclude(transit)) return;
1032
+ if (this._options.methodPrefix !== void 0 && !transit.method?.startsWith(this._options.methodPrefix)) return;
1033
+ const event = this._options.maxPayloadBytes === void 0 ? withoutPayloads(transit) : withCappedPayloads(transit, this._options.maxPayloadBytes);
1034
+ if (this._queue.length >= this._queueLimit) {
1035
+ this._queue.shift();
1036
+ this._dropped++;
1037
+ this._overflowPending++;
1038
+ }
1039
+ this._queue.push(event);
1040
+ if (!this._pumping) {
1041
+ this._pumping = true;
1042
+ queueMicrotask(() => void this._pump());
1043
+ }
1044
+ }
1045
+ dispose() {
1046
+ if (!this._active) return;
1047
+ this._active = false;
1048
+ this._dropped += this._queue.length;
1049
+ this._queue.length = 0;
1050
+ this._overflowPending = 0;
1051
+ this._onDispose();
1052
+ if (!this._pumping) this._complete();
1053
+ }
1054
+ async _pump() {
1055
+ try {
1056
+ while (this._active) {
1057
+ if (this._overflowPending > 0) {
1058
+ const dropped = this._overflowPending;
1059
+ this._overflowPending = 0;
1060
+ await this._send({
1061
+ type: "overflow",
1062
+ dropped
1063
+ });
1064
+ continue;
1065
+ }
1066
+ const event = this._queue.shift();
1067
+ if (event === void 0) break;
1068
+ await this._send(event);
1069
+ this._delivered++;
1070
+ }
1071
+ } catch {
1072
+ this.dispose();
1073
+ } finally {
1074
+ this._pumping = false;
1075
+ if (!this._active) this._complete();
1076
+ else if (this._queue.length > 0 || this._overflowPending > 0) {
1077
+ this._pumping = true;
1078
+ queueMicrotask(() => void this._pump());
1079
+ }
1080
+ }
1081
+ }
1082
+ _complete() {
1083
+ this._resolveClosed({
1084
+ delivered: this._delivered,
1085
+ dropped: this._dropped
1086
+ });
1087
+ }
1088
+ };
1089
+ function withoutPayloads(transit) {
1090
+ const { params: _params, result: _result, error, ...rest } = transit;
1091
+ if (error === void 0) return rest;
1092
+ return {
1093
+ ...rest,
1094
+ error: {
1095
+ code: error.code,
1096
+ message: error.message
1097
+ }
1098
+ };
1099
+ }
1100
+ function withCappedPayloads(transit, maxPayloadBytes) {
1101
+ return {
1102
+ ...transit,
1103
+ params: capPayload(transit.params, maxPayloadBytes),
1104
+ result: capPayload(transit.result, maxPayloadBytes),
1105
+ error: transit.error === void 0 ? void 0 : {
1106
+ ...transit.error,
1107
+ data: capPayload(transit.error.data, maxPayloadBytes)
1108
+ }
1109
+ };
1110
+ }
1111
+ function capPayload(value, maxBytes) {
1112
+ if (value === void 0) return void 0;
1113
+ if (maxBytes === Number.POSITIVE_INFINITY) return value;
1114
+ const json = JSON.stringify(value);
1115
+ if (json === void 0) return void 0;
1116
+ const encoded = new TextEncoder().encode(json);
1117
+ if (encoded.byteLength <= maxBytes) return value;
1118
+ const encoder = new TextEncoder();
1119
+ let preview = new TextDecoder().decode(encoded.slice(0, maxBytes));
1120
+ while (encoder.encode(preview).byteLength > maxBytes) preview = preview.slice(0, -1);
1121
+ return preview;
1122
+ }
1123
+ //#endregion
1124
+ export { NotificationType as A, defineInterface as C, sha256 as D, computeInterfaceHash as E, normalizeJsonSchema as F, notificationType as M, requestType as N, jcsCanonicalize as O, zodToSvcJsonSchema as P, InterfaceDefinition as S, EXTENSION_PREFIX as T, zTrafficEvent as _, topologyInterface as a, zTrafficTransitEvent as b, zParticipantDescriptorSource as c, zTopologyLink as d, zTopologyLinkEndpoint as f, zTopologyTransportInfo as g, zTopologyTransportEndpoint as h, nodeInterface as i, RequestType as j, jcsCanonicalizeBytes as k, zRouteClaim as l, zTopologyPort as m, TrafficFlowFilter as n, trafficInterface as o, zTopologyNode as p, TrafficWatchFlowTracker as r, zParticipantDescriptor as s, BoundedTrafficSubscription as t, zTopologyGraph as u, zTrafficOverflowEvent as v, interfaceFromSchema as w, zTrafficWatchResult as x, zTrafficTransitEndpoint as y };
1125
+
1126
+ //# sourceMappingURL=boundedTrafficSubscription-1L592xc7.js.map