@hediet/linkrpc 0.0.1 → 0.0.2

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 (31) hide show
  1. package/README.md +59 -0
  2. package/dist/chunks/{boundedTrafficSubscription-1L592xc7.js → boundedTrafficSubscription-XZ1KwXZC.js} +267 -6
  3. package/dist/chunks/boundedTrafficSubscription-XZ1KwXZC.js.map +1 -0
  4. package/dist/chunks/{hub.interfaces-BzWfsVT2.js → hub.interfaces-Bf4VfWNX.js} +2 -2
  5. package/dist/chunks/{hub.interfaces-BzWfsVT2.js.map → hub.interfaces-Bf4VfWNX.js.map} +1 -1
  6. package/dist/chunks/{hubAccess-DwTZPiI8.d.ts → hubAccess-C06qAKao.d.ts} +2 -2
  7. package/dist/chunks/{hubAccess-DwTZPiI8.d.ts.map → hubAccess-C06qAKao.d.ts.map} +1 -1
  8. package/dist/chunks/{hubFacade-CQflVkVC.js → hubFacade-BIB9CoAv.js} +2 -2
  9. package/dist/chunks/{hubFacade-CQflVkVC.js.map → hubFacade-BIB9CoAv.js.map} +1 -1
  10. package/dist/chunks/{hubFacade-Dkgw2pTi.d.ts → hubFacade-DtQpGpUy.d.ts} +2 -2
  11. package/dist/chunks/{hubFacade-Dkgw2pTi.d.ts.map → hubFacade-DtQpGpUy.d.ts.map} +1 -1
  12. package/dist/chunks/{linkRpcConnection-CtlQmetO.d.ts → linkRpcConnection-BadD37ok.d.ts} +125 -37
  13. package/dist/chunks/linkRpcConnection-BadD37ok.d.ts.map +1 -0
  14. package/dist/chunks/{src-D3NUIwyo.js → src-CAhXne71.js} +160 -198
  15. package/dist/chunks/src-CAhXne71.js.map +1 -0
  16. package/dist/hub/client/index.d.ts +3 -3
  17. package/dist/hub/client/index.js +3 -3
  18. package/dist/hub/common/index.d.ts +14 -14
  19. package/dist/hub/common/index.js +2 -2
  20. package/dist/index.d.ts +2 -2
  21. package/dist/index.js +3 -3
  22. package/dist/inspection/index.d.ts +1 -1
  23. package/dist/inspection/index.js +1 -1
  24. package/dist/node.d.ts +3 -3
  25. package/dist/node.js +4 -4
  26. package/dist/web.d.ts +2 -2
  27. package/dist/web.js +3 -3
  28. package/package.json +1 -1
  29. package/dist/chunks/boundedTrafficSubscription-1L592xc7.js.map +0 -1
  30. package/dist/chunks/linkRpcConnection-CtlQmetO.d.ts.map +0 -1
  31. package/dist/chunks/src-D3NUIwyo.js.map +0 -1
@@ -3,10 +3,9 @@
3
3
  * Licensed under the MIT License. See License.txt in the project root for license information.
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import { t as __exportAll } from "./rolldown-runtime-4LSo1kEK.js";
6
- import { A as NotificationType, C as defineInterface, D as sha256$1, M as notificationType, N as requestType, O as jcsCanonicalize, a as topologyInterface, i as nodeInterface, j as RequestType, k as jcsCanonicalizeBytes, o as trafficInterface, r as TrafficWatchFlowTracker, t as BoundedTrafficSubscription } from "./boundedTrafficSubscription-1L592xc7.js";
6
+ import { B as requestType, C as defineInterface, F as NotificationType, I as RequestType, M as sha256$1, N as jcsCanonicalize, P as jcsCanonicalizeBytes, R as isApplicationErrorValue, V as zodToSvcJsonSchema, a as topologyInterface, i as nodeInterface, o as trafficInterface, r as TrafficWatchFlowTracker, t as BoundedTrafficSubscription, z as notificationType } from "./boundedTrafficSubscription-XZ1KwXZC.js";
7
7
  import { array, boolean, enum as enum$1, int, nonnegative, number, object, optional, positive, string, union, unknown } from "zod/mini";
8
8
  import { safeParse } from "zod/v4/core";
9
- import { z } from "zod";
10
9
  //#region src/schema/assignability.ts
11
10
  /**
12
11
  * Structural subtype check: returns `true` iff every JSON value matching
@@ -19,6 +18,10 @@ import { z } from "zod";
19
18
  function isAssignable(sub, sup, components = {}) {
20
19
  return _check(sub, sup, components, /* @__PURE__ */ new Set());
21
20
  }
21
+ /** Match one JSON value against the structural LinkRPC subset without transforming it. */
22
+ function matchesJsonSchema(value, schema, components = {}) {
23
+ return _matches(value, schema, components, /* @__PURE__ */ new Set());
24
+ }
22
25
  function _check(sub, sup, c, seen) {
23
26
  if (sup === true) return true;
24
27
  if (sub === false) return true;
@@ -119,8 +122,9 @@ function _matches(v, sup, c, seen) {
119
122
  if (sup === true) return true;
120
123
  if (sup === false) return false;
121
124
  if (_isRef(sup)) {
125
+ if (seen.has(sup.$ref)) return false;
122
126
  const r = _resolveRef(sup, c);
123
- return r ? _matches(v, r, c, seen) : false;
127
+ return r ? _matches(v, r, c, new Set(seen).add(sup.$ref)) : false;
124
128
  }
125
129
  if (_isUnion(sup)) return _branches(sup).some((b) => _matches(v, b, c, seen));
126
130
  if (_isConst(sup)) return _jsonEq(v, sup.const);
@@ -131,12 +135,12 @@ function _matches(v, sup, c, seen) {
131
135
  case "number": return typeof v === "number";
132
136
  case "integer": return typeof v === "number" && Number.isInteger(v);
133
137
  case "string": return typeof v === "string";
134
- case "array": return Array.isArray(v) && _matchesArray(v, sup, c, seen);
135
- case "object": return v !== null && typeof v === "object" && !Array.isArray(v) && _matchesObject(v, sup, c, seen);
138
+ case "array": return Array.isArray(v) && _matchesArray(v, sup, c);
139
+ case "object": return v !== null && typeof v === "object" && !Array.isArray(v) && _matchesObject(v, sup, c);
136
140
  default: return false;
137
141
  }
138
142
  }
139
- function _matchesArray(v, sup, c, seen) {
143
+ function _matchesArray(v, sup, c) {
140
144
  const prefix = sup.prefixItems ?? [];
141
145
  const rest = _restOf(sup);
142
146
  if (rest === false && v.length !== prefix.length) {
@@ -145,16 +149,16 @@ function _matchesArray(v, sup, c, seen) {
145
149
  for (let i = 0; i < v.length; i++) {
146
150
  const s = prefix[i] ?? (rest === false ? false : rest);
147
151
  if (s === false) return false;
148
- if (!_matches(v[i], s, c, seen)) return false;
152
+ if (!_matches(v[i], s, c, /* @__PURE__ */ new Set())) return false;
149
153
  }
150
154
  return true;
151
155
  }
152
- function _matchesObject(v, sup, c, seen) {
153
- for (const k of sup.required ?? []) if (!(k in v)) return false;
156
+ function _matchesObject(v, sup, c) {
157
+ for (const k of sup.required ?? []) if (!Object.hasOwn(v, k)) return false;
154
158
  for (const [k, val] of Object.entries(v)) {
155
- const s = sup.properties[k] ?? sup.additionalProperties;
159
+ const s = Object.hasOwn(sup.properties, k) ? sup.properties[k] : sup.additionalProperties;
156
160
  if (s === false) return false;
157
- if (!_matches(val, s, c, seen)) return false;
161
+ if (!_matches(val, s, c, /* @__PURE__ */ new Set())) return false;
158
162
  }
159
163
  return true;
160
164
  }
@@ -218,59 +222,6 @@ function _jsonEq(a, b) {
218
222
  return false;
219
223
  }
220
224
  //#endregion
221
- //#region src/schema/assertSchemaReferences.ts
222
- const componentPrefix = "#/components/schemas/";
223
- function componentSchemaRef(name) {
224
- return componentPrefix + name.replace(/~/g, "~0").replace(/\//g, "~1");
225
- }
226
- function componentSchemaName(ref) {
227
- if (!ref.startsWith(componentPrefix)) throw new Error(`Invalid component reference: ${ref}`);
228
- const token = ref.slice(21);
229
- if (token.includes("/") || /~(?:[^01]|$)/.test(token)) throw new Error(`Invalid component reference token: ${ref}`);
230
- return token.replace(/~1/g, "/").replace(/~0/g, "~");
231
- }
232
- /**
233
- * Check the finite schema graph without interpreting JSON literal payloads.
234
- * A reference/union-only cycle is invalid; descending into an object member
235
- * or an array item guards a cycle, but does not imply the schema is nonempty.
236
- */
237
- function assertSchemaReferences(roots, components = {}) {
238
- const nodes = /* @__PURE__ */ new Set();
239
- const pending = [...roots, ...Object.values(components)];
240
- const unguarded = /* @__PURE__ */ new Map();
241
- while (pending.length > 0) {
242
- const node = pending.pop();
243
- if (typeof node === "boolean" || nodes.has(node)) continue;
244
- nodes.add(node);
245
- const edges = [];
246
- if ("$ref" in node) {
247
- const name = componentSchemaName(node.$ref);
248
- if (!Object.hasOwn(components, name)) throw new Error(`Unresolved component reference: ${node.$ref}`);
249
- edges.push(components[name]);
250
- }
251
- if ("anyOf" in node) edges.push(...node.anyOf);
252
- if ("oneOf" in node) edges.push(...node.oneOf);
253
- unguarded.set(node, edges);
254
- pending.push(...edges);
255
- if ("type" in node && node.type === "object") pending.push(...Object.values(node.properties ?? {}), node.additionalProperties);
256
- if ("type" in node && node.type === "array") {
257
- if ("prefixItems" in node) pending.push(...node.prefixItems);
258
- if (node.items !== void 0) pending.push(node.items);
259
- }
260
- }
261
- const visiting = /* @__PURE__ */ new Set();
262
- const checked = /* @__PURE__ */ new Set();
263
- const visit = (node) => {
264
- if (typeof node === "boolean" || checked.has(node)) return;
265
- if (visiting.has(node)) throw new Error("Unguarded recursive schema: cycle does not descend into a child value");
266
- visiting.add(node);
267
- for (const child of unguarded.get(node) ?? []) visit(child);
268
- visiting.delete(node);
269
- checked.add(node);
270
- };
271
- for (const node of nodes) visit(node);
272
- }
273
- //#endregion
274
225
  //#region src/schema/materializeJsonSchema.ts
275
226
  /**
276
227
  * Export a LinkRPC schema and its components as standalone JSON Schema
@@ -357,128 +308,6 @@ function isRecord(value) {
357
308
  return value !== null && typeof value === "object" && !Array.isArray(value);
358
309
  }
359
310
  //#endregion
360
- //#region src/schema/schemaToZod.ts
361
- /**
362
- * Create a recursive LinkRPC-schema validator materializer. Component
363
- * references are lazy, so self and mutual recursion remain guarded.
364
- */
365
- function createSchemaToZod(components = {}) {
366
- assertSchemaReferences([], components);
367
- const refs = /* @__PURE__ */ new Map();
368
- const component = (name) => {
369
- const existing = refs.get(name);
370
- if (existing !== void 0) return existing;
371
- const source = components[name];
372
- if (source === void 0) throw new Error(`schemaToZod: dangling component reference "${name}"`);
373
- const lazy = z.lazy(() => compile(source));
374
- refs.set(name, lazy);
375
- return lazy;
376
- };
377
- const compile = (schema) => {
378
- if (schema === true) return z.unknown();
379
- if (schema === false) return z.never();
380
- const raw = schema;
381
- if (Array.isArray(raw.type)) return union$1(raw.type.map((type) => compile({
382
- ...raw,
383
- type
384
- })));
385
- let base;
386
- if ("$ref" in schema) base = component(componentSchemaName(schema.$ref));
387
- else if ("const" in schema) base = valueSchema(schema.const);
388
- else if ("enum" in schema) base = union$1(schema.enum.map(valueSchema));
389
- else if ("anyOf" in schema) base = union$1(schema.anyOf.map(compile));
390
- else if ("oneOf" in schema) base = union$1(schema.oneOf.map(compile));
391
- else if (isAnnotationOnlySchema(raw)) base = z.unknown();
392
- else switch (schema.type) {
393
- case "null":
394
- base = z.null();
395
- break;
396
- case "boolean":
397
- base = z.boolean();
398
- break;
399
- case "string":
400
- base = stringSchema(schema.format);
401
- break;
402
- case "integer":
403
- base = z.number().int();
404
- break;
405
- case "number":
406
- base = z.number();
407
- break;
408
- case "array":
409
- if ("prefixItems" in schema) {
410
- const tuple = z.tuple(schema.prefixItems.map(compile));
411
- base = schema.items !== void 0 && schema.items !== false ? tuple.rest(compile(schema.items)) : tuple;
412
- } else base = z.array(compile(schema.items));
413
- break;
414
- case "object": {
415
- const required = new Set(schema.required ?? []);
416
- const shape = {};
417
- for (const [name, property] of Object.entries(schema.properties)) {
418
- const validator = compile(property);
419
- shape[name] = required.has(name) ? validator : validator.optional();
420
- }
421
- const object = z.object(shape);
422
- if (schema.additionalProperties === false) base = object.strict();
423
- else if (schema.additionalProperties === true) base = object.loose();
424
- else base = object.catchall(compile(schema.additionalProperties));
425
- break;
426
- }
427
- }
428
- return base;
429
- };
430
- return { toZod(schema) {
431
- assertSchemaReferences([schema], components);
432
- return compile(schema);
433
- } };
434
- }
435
- function isAnnotationOnlySchema(schema) {
436
- return ![
437
- "$ref",
438
- "const",
439
- "enum",
440
- "anyOf",
441
- "oneOf",
442
- "type",
443
- "properties",
444
- "items",
445
- "prefixItems",
446
- "additionalProperties"
447
- ].some((key) => Object.hasOwn(schema, key));
448
- }
449
- function schemaToZod(schema, components = {}) {
450
- return createSchemaToZod(components).toZod(schema);
451
- }
452
- function union$1(items) {
453
- if (items.length === 0) return z.never();
454
- if (items.length === 1) return items[0];
455
- return z.union(items);
456
- }
457
- function valueSchema(expected) {
458
- return z.unknown().refine((actual) => jsonValueEqual(actual, expected), { message: `Expected ${JSON.stringify(expected)}` });
459
- }
460
- function jsonValueEqual(actual, expected) {
461
- if (Object.is(actual, expected)) return true;
462
- if (Array.isArray(actual) && Array.isArray(expected)) return actual.length === expected.length && actual.every((value, index) => jsonValueEqual(value, expected[index]));
463
- if (actual !== null && expected !== null && typeof actual === "object" && typeof expected === "object" && !Array.isArray(actual) && !Array.isArray(expected)) {
464
- const actualRecord = actual;
465
- const expectedRecord = expected;
466
- const keys = Object.keys(actualRecord);
467
- return keys.length === Object.keys(expectedRecord).length && keys.every((key) => Object.hasOwn(expectedRecord, key) && jsonValueEqual(actualRecord[key], expectedRecord[key]));
468
- }
469
- return false;
470
- }
471
- function stringSchema(format) {
472
- switch (format) {
473
- case "email": return z.email();
474
- case "uri":
475
- case "url": return z.url();
476
- case "uuid": return z.uuid();
477
- case "date-time": return z.iso.datetime();
478
- default: return z.string();
479
- }
480
- }
481
- //#endregion
482
311
  //#region src/connection/bareInterfaceTarget.ts
483
312
  /**
484
313
  * Bundle an interface definition with metadata-free foreign-protocol
@@ -566,13 +395,15 @@ var CodeWriter = class {
566
395
  * components receive explicit payload types; other types remain Zod-inferred.
567
396
  */
568
397
  function generateTsInterface(schema, options = {}) {
398
+ _validateErrors(schema.methods);
569
399
  const linkRpcImport = options.linkRpcImport ?? "@hediet/linkrpc";
570
400
  const exportName = options.exportName ?? _deriveExportName(schema.id);
571
401
  const preserveWireSchema = options.preserveWireSchema ?? false;
572
402
  if (options.bareTarget !== void 0) validateBarePrefix(options.bareTarget.prefix, "bareInterfaceTarget");
573
403
  const w = new CodeWriter();
574
404
  const bareTargetImport = options.bareTarget === void 0 ? "" : "bareInterfaceTarget, ";
575
- const definitionImport = preserveWireSchema ? `${bareTargetImport}InterfaceDefinition, notificationType, requestType, type LinkRpcInterfaceSchema` : `${bareTargetImport}defineInterface, notificationType, requestType`;
405
+ const errorImport = Object.values(schema.methods).some((method) => (method.errors?.length ?? 0) > 0) ? "applicationError, " : "";
406
+ const definitionImport = preserveWireSchema ? `${errorImport}${bareTargetImport}InterfaceDefinition, notificationType, requestType, type LinkRpcInterfaceSchema` : `${errorImport}${bareTargetImport}defineInterface, notificationType, requestType`;
576
407
  w.writeLine(`import { ${definitionImport} } from "${linkRpcImport}";`);
577
408
  w.writeLine(`import { z } from "zod";`);
578
409
  w.writeLine();
@@ -715,6 +546,20 @@ function _writeMethod(w, method, components, preserveWireSchema) {
715
546
  }
716
547
  w.dedent();
717
548
  w.append(")");
549
+ if ((method.errors?.length ?? 0) > 0) {
550
+ w.append(".withErrors([").newline();
551
+ w.indent();
552
+ for (const error of method.errors) {
553
+ w.append(`applicationError(${error.code}, ${JSON.stringify(error.message)}`);
554
+ if (error.data !== void 0) {
555
+ w.append(", ");
556
+ _writeSchema(w, error.data, components, preserveWireSchema);
557
+ }
558
+ w.append("),").newline();
559
+ }
560
+ w.dedent();
561
+ w.append("] as const)");
562
+ }
718
563
  if (method.clientStream !== void 0 || method.serverStream !== void 0) {
719
564
  w.append(".withStream({").newline();
720
565
  w.indent();
@@ -732,6 +577,19 @@ function _writeMethod(w, method, components, preserveWireSchema) {
732
577
  w.append("})");
733
578
  }
734
579
  }
580
+ function _validateErrors(methods) {
581
+ for (const [name, method] of Object.entries(methods)) {
582
+ if (method.result === void 0 && method.errors !== void 0) throw new Error(`generateInterface: notification "${name}" cannot declare errors`);
583
+ const seen = /* @__PURE__ */ new Set();
584
+ for (const error of method.errors ?? []) {
585
+ if (typeof error.message !== "string") throw new Error(`generateInterface: error message on "${name}" is not a string`);
586
+ if (!Number.isInteger(error.code) || error.code < -2147483648 || error.code > 2147483647) throw new Error(`generateInterface: error code ${error.code} on "${name}" is not a signed i32`);
587
+ if (error.code >= -32768 && error.code <= -32e3 || error.code === -32800) throw new Error(`generateInterface: error code ${error.code} on "${name}" is reserved`);
588
+ if (seen.has(error.code)) throw new Error(`generateInterface: duplicate error code ${error.code} on "${name}"`);
589
+ seen.add(error.code);
590
+ }
591
+ }
592
+ }
735
593
  function _collectMemberDocs(method) {
736
594
  const docs = {};
737
595
  if (method.description !== void 0) docs.description = method.description;
@@ -2178,12 +2036,16 @@ var Channel = class Channel {
2178
2036
  };
2179
2037
  var RpcError = class extends Error {
2180
2038
  code;
2039
+ origin;
2181
2040
  data;
2182
- constructor(message, code, data) {
2041
+ hasData;
2042
+ constructor(message, code, data, origin = "local", hasData = data !== void 0) {
2183
2043
  super(message);
2184
2044
  this.code = code;
2185
- this.data = data;
2045
+ this.origin = origin;
2186
2046
  this.name = "RpcError";
2047
+ this.hasData = hasData;
2048
+ if (hasData) this.data = data;
2187
2049
  }
2188
2050
  };
2189
2051
  //#endregion
@@ -3350,7 +3212,7 @@ var JsonRpcChannel = class JsonRpcChannel {
3350
3212
  this._streamListeners.delete(key);
3351
3213
  if ("error" in m) {
3352
3214
  const e = m.error;
3353
- const err = new RpcError(e.message, e.code, e.data);
3215
+ const err = new RpcError(e.message, e.code, e.data, "remote", Object.hasOwn(e, "data"));
3354
3216
  pending.reject(err);
3355
3217
  } else pending.resolve(m.result);
3356
3218
  return;
@@ -4043,18 +3905,20 @@ var LinkRpcConnection = class LinkRpcConnection {
4043
3905
  } : sendOpts;
4044
3906
  this._validateOutboundParamsFor(member, wireMethod, params);
4045
3907
  const call = this.channel.sendRequestWithStream(wireMethod, params, channelOpts);
4046
- const result = call.result.then((raw) => validateWireResult(member.resultSchema, raw, wireMethod));
4047
- return Object.assign(result, {
3908
+ const checked = addCheckedResult(call.result.then((raw) => validateWireResult(member.resultSchema, raw, wireMethod)), member);
3909
+ return Object.assign(checked, {
4048
3910
  send: async (payload) => call.send(payload),
4049
3911
  cancel: async (reason) => call.cancel(reason),
4050
3912
  dispose: (reason) => call.dispose?.(reason),
4051
3913
  ping: () => call.ping()
4052
3914
  });
4053
3915
  };
4054
- } else proxy[name] = async (params) => {
4055
- this._validateOutboundParamsFor(member, wireMethod, params);
4056
- const raw = await this.channel.sendRequest(wireMethod, params, sendOpts);
4057
- return validateWireResult(member.resultSchema, raw, wireMethod);
3916
+ } else proxy[name] = (params) => {
3917
+ return addCheckedResult((async () => {
3918
+ this._validateOutboundParamsFor(member, wireMethod, params);
3919
+ const raw = await this.channel.sendRequest(wireMethod, params, sendOpts);
3920
+ return validateWireResult(member.resultSchema, raw, wireMethod);
3921
+ })(), member);
4058
3922
  };
4059
3923
  } else {
4060
3924
  const notify = (params) => {
@@ -4089,6 +3953,8 @@ var LinkRpcConnection = class LinkRpcConnection {
4089
3953
  const stream = this._buildStreamApi(call.stream, call.signal, member);
4090
3954
  try {
4091
3955
  const result = await handler(parsedParams.data, call.context, stream);
3956
+ const encodedError = encodeApplicationError(member, result);
3957
+ if (encodedError !== void 0) return { error: encodedError };
4092
3958
  validateValue(member.resultSchema, result, `Invalid result for ${call.method}`, ErrorCode.internalError);
4093
3959
  return { result: result === void 0 ? null : result };
4094
3960
  } catch (e) {
@@ -4273,6 +4139,102 @@ function directoryWatcherMatchesEntry(watcher, entry) {
4273
4139
  const serviceId = entry.serviceId ?? "";
4274
4140
  return (watcher.interfaceId === void 0 || watcher.interfaceId === entry.iface.info.id) && (watcher.interfaceIdPrefix === void 0 || entry.iface.info.id.startsWith(watcher.interfaceIdPrefix)) && (watcher.serviceId === void 0 || watcher.serviceId === serviceId) && serviceIdMatchesScopes(serviceId, watcher.serviceIdScopes);
4275
4141
  }
4142
+ function addCheckedResult(promise, member) {
4143
+ return Object.assign(promise, { result: async () => {
4144
+ try {
4145
+ return {
4146
+ ok: true,
4147
+ value: await promise
4148
+ };
4149
+ } catch (cause) {
4150
+ return {
4151
+ ok: false,
4152
+ error: decodeCheckedError(cause, member.applicationErrors)
4153
+ };
4154
+ }
4155
+ } });
4156
+ }
4157
+ function decodeCheckedError(cause, descriptors) {
4158
+ if (!(cause instanceof RpcError) || cause.origin !== "remote") return {
4159
+ kind: "local",
4160
+ cause
4161
+ };
4162
+ const descriptor = descriptors.find((candidate) => candidate.code === cause.code && candidate.message === cause.message);
4163
+ if (descriptor !== void 0) {
4164
+ if (descriptor.dataSchema === void 0 && !cause.hasData) return {
4165
+ kind: "application",
4166
+ code: descriptor.code,
4167
+ message: descriptor.message
4168
+ };
4169
+ if (descriptor.dataSchema !== void 0 && cause.hasData && matchesApplicationData(descriptor.dataSchema, cause.data)) {
4170
+ if (safeParse(descriptor.dataSchema, cause.data).success) return {
4171
+ kind: "application",
4172
+ code: descriptor.code,
4173
+ message: descriptor.message,
4174
+ data: cause.data
4175
+ };
4176
+ }
4177
+ }
4178
+ return {
4179
+ kind: "remote",
4180
+ code: cause.code,
4181
+ message: cause.message,
4182
+ ...cause.hasData ? { data: cause.data } : {}
4183
+ };
4184
+ }
4185
+ function encodeApplicationError(member, value) {
4186
+ if (!isApplicationErrorValue(value)) return void 0;
4187
+ const candidate = value;
4188
+ const descriptor = member.applicationErrors.find((error) => error.code === candidate.code && error.message === candidate.message);
4189
+ if (descriptor === void 0) throw new RpcError(`Undeclared application error ${String(candidate.code)}`, ErrorCode.internalError);
4190
+ const hasData = Object.hasOwn(candidate, "data");
4191
+ if (descriptor.dataSchema === void 0) {
4192
+ if (hasData) throw new RpcError(`Application error ${descriptor.code} must not contain data`, ErrorCode.internalError);
4193
+ return {
4194
+ code: descriptor.code,
4195
+ message: descriptor.message
4196
+ };
4197
+ }
4198
+ if (!hasData) throw new RpcError(`Application error ${descriptor.code} requires data`, ErrorCode.internalError);
4199
+ if (!matchesApplicationData(descriptor.dataSchema, candidate.data)) throw new RpcError(`Invalid data for application error ${descriptor.code}`, ErrorCode.internalError, { issues: [{ message: "Data must be JSON matching the declared wire schema" }] });
4200
+ const parsed = safeParse(descriptor.dataSchema, candidate.data);
4201
+ if (!parsed.success) throw new RpcError(`Invalid data for application error ${descriptor.code}`, ErrorCode.internalError, { issues: parsed.error.issues });
4202
+ return {
4203
+ code: descriptor.code,
4204
+ message: descriptor.message,
4205
+ data: candidate.data
4206
+ };
4207
+ }
4208
+ /** Reject values JSON serialization would silently omit, coerce, or replace via toJSON. */
4209
+ function isWireJsonValue(value, ancestors = /* @__PURE__ */ new Set()) {
4210
+ if (value === null || typeof value === "string" || typeof value === "boolean") return true;
4211
+ if (typeof value === "number") return Number.isFinite(value);
4212
+ if (typeof value !== "object" || ancestors.has(value)) return false;
4213
+ if (!Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) return false;
4214
+ ancestors.add(value);
4215
+ const children = Array.isArray(value) ? value.values() : Object.values(value);
4216
+ for (const child of children) if (!isWireJsonValue(child, ancestors)) return false;
4217
+ ancestors.delete(value);
4218
+ return true;
4219
+ }
4220
+ const applicationDataSchemas = /* @__PURE__ */ new WeakMap();
4221
+ function matchesApplicationData(schema, value) {
4222
+ if (!isWireJsonValue(value)) return false;
4223
+ let wire = applicationDataSchemas.get(schema);
4224
+ if (wire === void 0) {
4225
+ const components = {};
4226
+ wire = {
4227
+ schema: zodToSvcJsonSchema(schema, {
4228
+ methodName: "applicationError",
4229
+ schemaPosition: "data",
4230
+ components
4231
+ }),
4232
+ components
4233
+ };
4234
+ applicationDataSchemas.set(schema, wire);
4235
+ }
4236
+ return matchesJsonSchema(value, wire.schema, { schemas: wire.components });
4237
+ }
4276
4238
  function validateWireResult(schema, raw, wireMethod) {
4277
4239
  const value = normalizeWireResult(schema, raw);
4278
4240
  validateValue(schema, value, `Invalid result for ${wireMethod}`, ErrorCode.internalError);
@@ -7790,6 +7752,6 @@ async function createSeededSigningIdentity(opts) {
7790
7752
  return KeypairSigningIdentity.fromKeypair(ed);
7791
7753
  }
7792
7754
  //#endregion
7793
- export { walkHubDetailed as $, bareInterfaceTarget as $t, attachCapabilities as A, PRINCIPAL_PREFIX as At, LinkRpcConnection as B, isRequest as Bt, identityStorageInterface as C, getKeyId as Ct, PublicWrappingIdentity as D, signingInput as Dt, PublicSigningIdentity as E, signingDomainValue as Et, generateX25519Keypair as F, principalForPublicKey as Ft, fetchDirectory as G, StreamDir as Gt, JsonRpcChannel as H, STREAM_METHOD as Ht, formatEndpointUri as I, publicKeyForKeyId as It, intersectServiceIdScopes as J, directoryInterface as Jt, fetchSchema as K, streamInterface as Kt, isHubEndpoint as L, resolveSigningKey as Lt, verifyRpcCall as M, bytesToBase64Url as Mt, crypto_exports as N, keyIdForPrincipal as Nt, Principal as O, withSignature as Ot, generateKeypair as P, keyIdForPublicKey as Pt, walkHub as Q, generateTsInterface as Qt, parseEndpointUri as R, ErrorCode as Rt, identityInterface as S, LINKRPC_UNSIGNED_KEY as St, KeypairSigningIdentity as T, signedHash as Tt, DEFAULT_WALK_DEPTH as U, StreamControlReason as Ut, ServiceHandle as V, isResponse as Vt, HubDirectoryExplorer as W, StreamControlType as Wt, serviceIdMatchesPattern as X, schemasInterface as Xt, normalizeServiceIdScopes as Y, directoryWatchNever as Yt, serviceIdMatchesScopes as Z, zServiceIdPattern as Zt, InMemoryManagedIdentity as _, HUBRPC_META_KEY as _t, verifyCall as a, componentSchemaRef as an, TransportPair as at, registerIdentityOnOverlay as b, LINKRPC_META_KEY as bt, invoke as c, requireObjectParams as ct, prefix as d, parseMethodName as dt, createSchemaToZod as en, DEFAULT_RPC_TIMEOUT_MS as et, signCapability as f, capabilityPermits as ft, createManagedPrincipal as g, permissionPermits as gt, PrincipalWithStore as h, permissionMatchesTarget as ht, signParams as i, componentSchemaName as in, MultiplexedTransport as it, signRpcCall as j, base64UrlToBytes$1 as jt, CapBag as k, KEY_ID_PREFIX as kt, issueCapability as l, stripLinkRpcWireMeta as lt, SigningSender as m, matchParams as mt, createSeededMemoryPrincipal as n, materializeJsonSchema as nn, Channel as nt, capBagFreshAt as o, isAssignable as on, connectTransports as ot, OneShotCapStaging as p, hasSignedCapabilityShape as pt, findMethodInSchema as q, defaultsInterface as qt, createSeededSigningIdentity as r, assertSchemaReferences as rn, RpcError as rt, capabilityFreshAt as s, traceMessageTransport as st, createMemoryPrincipal as t, schemaToZod as tn, withRpcTimeout as tt, permits as u, methodNameToTarget as ut, InMemoryManagedIdentityStorage as v, HUBRPC_SIGNATURE_KEY as vt, KeypairIdentity as w, readSignature as wt, registerLazyIdentityOnOverlay as x, LINKRPC_SIGNATURE_KEY as xt, createManagedIdentity as y, HUBRPC_UNSIGNED_KEY as yt, ChannelConnector as z, isNotification as zt };
7755
+ export { walkHubDetailed as $, bareInterfaceTarget as $t, attachCapabilities as A, PRINCIPAL_PREFIX as At, LinkRpcConnection as B, isRequest as Bt, identityStorageInterface as C, getKeyId as Ct, PublicWrappingIdentity as D, signingInput as Dt, PublicSigningIdentity as E, signingDomainValue as Et, generateX25519Keypair as F, principalForPublicKey as Ft, fetchDirectory as G, StreamDir as Gt, JsonRpcChannel as H, STREAM_METHOD as Ht, formatEndpointUri as I, publicKeyForKeyId as It, intersectServiceIdScopes as J, directoryInterface as Jt, fetchSchema as K, streamInterface as Kt, isHubEndpoint as L, resolveSigningKey as Lt, verifyRpcCall as M, bytesToBase64Url as Mt, crypto_exports as N, keyIdForPrincipal as Nt, Principal as O, withSignature as Ot, generateKeypair as P, keyIdForPublicKey as Pt, walkHub as Q, generateTsInterface as Qt, parseEndpointUri as R, ErrorCode as Rt, identityInterface as S, LINKRPC_UNSIGNED_KEY as St, KeypairSigningIdentity as T, signedHash as Tt, DEFAULT_WALK_DEPTH as U, StreamControlReason as Ut, ServiceHandle as V, isResponse as Vt, HubDirectoryExplorer as W, StreamControlType as Wt, serviceIdMatchesPattern as X, schemasInterface as Xt, normalizeServiceIdScopes as Y, directoryWatchNever as Yt, serviceIdMatchesScopes as Z, zServiceIdPattern as Zt, InMemoryManagedIdentity as _, HUBRPC_META_KEY as _t, verifyCall as a, TransportPair as at, registerIdentityOnOverlay as b, LINKRPC_META_KEY as bt, invoke as c, requireObjectParams as ct, prefix as d, parseMethodName as dt, materializeJsonSchema as en, DEFAULT_RPC_TIMEOUT_MS as et, signCapability as f, capabilityPermits as ft, createManagedPrincipal as g, permissionPermits as gt, PrincipalWithStore as h, permissionMatchesTarget as ht, signParams as i, MultiplexedTransport as it, signRpcCall as j, base64UrlToBytes$1 as jt, CapBag as k, KEY_ID_PREFIX as kt, issueCapability as l, stripLinkRpcWireMeta as lt, SigningSender as m, matchParams as mt, createSeededMemoryPrincipal as n, matchesJsonSchema as nn, Channel as nt, capBagFreshAt as o, connectTransports as ot, OneShotCapStaging as p, hasSignedCapabilityShape as pt, findMethodInSchema as q, defaultsInterface as qt, createSeededSigningIdentity as r, RpcError as rt, capabilityFreshAt as s, traceMessageTransport as st, createMemoryPrincipal as t, isAssignable as tn, withRpcTimeout as tt, permits as u, methodNameToTarget as ut, InMemoryManagedIdentityStorage as v, HUBRPC_SIGNATURE_KEY as vt, KeypairIdentity as w, readSignature as wt, registerLazyIdentityOnOverlay as x, LINKRPC_SIGNATURE_KEY as xt, createManagedIdentity as y, HUBRPC_UNSIGNED_KEY as yt, ChannelConnector as z, isNotification as zt };
7794
7756
 
7795
- //# sourceMappingURL=src-D3NUIwyo.js.map
7757
+ //# sourceMappingURL=src-CAhXne71.js.map