@private.me/xbind 3.0.0 → 3.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 (217) hide show
  1. package/README.md +55 -7
  2. package/dist-standalone/_deps/mldsa-wasm/dist/mldsa.js +1920 -1
  3. package/dist-standalone/_deps/shared/cjs/errors.js +729 -1
  4. package/dist-standalone/_deps/shared/cjs/index.js +463 -1
  5. package/dist-standalone/_deps/shared/cjs/types.js +315 -1
  6. package/dist-standalone/_deps/shared/errors.js +244 -1
  7. package/dist-standalone/_deps/shared/index.js +72 -1
  8. package/dist-standalone/_deps/shared/types.js +86 -1
  9. package/dist-standalone/_deps/ux-helpers/cjs/errors.js +1 -1
  10. package/dist-standalone/_deps/ux-helpers/cjs/index.js +1 -1
  11. package/dist-standalone/_deps/ux-helpers/cjs/pagination.js +1 -1
  12. package/dist-standalone/_deps/ux-helpers/cjs/progress.js +1 -1
  13. package/dist-standalone/_deps/ux-helpers/cjs/search.js +1 -1
  14. package/dist-standalone/_deps/ux-helpers/cjs/types.js +1 -1
  15. package/dist-standalone/_deps/ux-helpers/errors.js +1 -1
  16. package/dist-standalone/_deps/ux-helpers/index.js +1 -1
  17. package/dist-standalone/_deps/ux-helpers/pagination.js +1 -1
  18. package/dist-standalone/_deps/ux-helpers/progress.js +1 -1
  19. package/dist-standalone/_deps/ux-helpers/search.js +1 -1
  20. package/dist-standalone/_deps/xchange/auto-accept.js +1 -1
  21. package/dist-standalone/_deps/xchange/cjs/auto-accept.js +1 -1
  22. package/dist-standalone/_deps/xchange/cjs/errors.js +1 -1
  23. package/dist-standalone/_deps/xchange/cjs/index.js +1 -1
  24. package/dist-standalone/_deps/xchange/cjs/invite-client.js +1 -1
  25. package/dist-standalone/_deps/xchange/cjs/lazy-init.js +1 -1
  26. package/dist-standalone/_deps/xchange/cjs/trust-integration.js +1 -1
  27. package/dist-standalone/_deps/xchange/cjs/xchange.js +1 -1
  28. package/dist-standalone/_deps/xchange/errors.js +1 -1
  29. package/dist-standalone/_deps/xchange/index.js +1 -1
  30. package/dist-standalone/_deps/xchange/invite-client.js +1 -1
  31. package/dist-standalone/_deps/xchange/lazy-init.js +1 -1
  32. package/dist-standalone/_deps/xchange/trust-integration.js +1 -1
  33. package/dist-standalone/_deps/xchange/xchange.js +1 -1
  34. package/dist-standalone/_deps/xregistry/cjs/discovery.js +1 -1
  35. package/dist-standalone/_deps/xregistry/cjs/errors.js +1 -1
  36. package/dist-standalone/_deps/xregistry/cjs/index.js +1 -1
  37. package/dist-standalone/_deps/xregistry/cjs/registry.js +1 -1
  38. package/dist-standalone/_deps/xregistry/cjs/schema.js +1 -1
  39. package/dist-standalone/_deps/xregistry/cjs/types.js +1 -1
  40. package/dist-standalone/_deps/xregistry/discovery.js +1 -1
  41. package/dist-standalone/_deps/xregistry/errors.js +1 -1
  42. package/dist-standalone/_deps/xregistry/index.js +1 -1
  43. package/dist-standalone/_deps/xregistry/registry.js +1 -1
  44. package/dist-standalone/_deps/xregistry/schema.js +1 -1
  45. package/dist-standalone/_deps/xregistry/types.js +1 -1
  46. package/dist-standalone/agent-call.js +659 -1
  47. package/dist-standalone/agent-sdk.js +328 -1
  48. package/dist-standalone/agent.js +1800 -1
  49. package/dist-standalone/approval.js +193 -1
  50. package/dist-standalone/async-iterators.js +382 -1
  51. package/dist-standalone/auth.js +219 -1
  52. package/dist-standalone/auto-accept.js +229 -1
  53. package/dist-standalone/backup-config.js +201 -1
  54. package/dist-standalone/backup.js +326 -1
  55. package/dist-standalone/batch-operations.js +388 -1
  56. package/dist-standalone/cancellation.js +477 -1
  57. package/dist-standalone/checkpoint.js +186 -1
  58. package/dist-standalone/circuit-breaker.js +468 -1
  59. package/dist-standalone/cjs/agent-call.js +701 -1
  60. package/dist-standalone/cjs/agent-sdk.js +332 -1
  61. package/dist-standalone/cjs/agent.js +1837 -1
  62. package/dist-standalone/cjs/approval.js +199 -1
  63. package/dist-standalone/cjs/async-iterators.js +392 -1
  64. package/dist-standalone/cjs/auth.js +225 -1
  65. package/dist-standalone/cjs/auto-accept.js +233 -1
  66. package/dist-standalone/cjs/backup-config.js +207 -1
  67. package/dist-standalone/cjs/backup.js +330 -1
  68. package/dist-standalone/cjs/batch-operations.js +397 -1
  69. package/dist-standalone/cjs/cancellation.js +490 -1
  70. package/dist-standalone/cjs/checkpoint.js +193 -1
  71. package/dist-standalone/cjs/circuit-breaker.js +476 -1
  72. package/dist-standalone/cjs/cli/init.js +492 -1
  73. package/dist-standalone/cjs/config-validation.js +522 -1
  74. package/dist-standalone/cjs/connect.js +312 -1
  75. package/dist-standalone/cjs/connection-pool.js +506 -1
  76. package/dist-standalone/cjs/correlation-id.js +339 -1
  77. package/dist-standalone/cjs/crypto-utils.js +176 -1
  78. package/dist-standalone/cjs/debug-mode.js +534 -1
  79. package/dist-standalone/cjs/did-document.js +101 -1
  80. package/dist-standalone/cjs/did-privateme.js +130 -1
  81. package/dist-standalone/cjs/did-web.js +201 -1
  82. package/dist-standalone/cjs/discovery.js +462 -1
  83. package/dist-standalone/cjs/dual-mode.js +251 -1
  84. package/dist-standalone/cjs/email-templates.js +313 -1
  85. package/dist-standalone/cjs/email-transport.js +239 -1
  86. package/dist-standalone/cjs/envelope.js +538 -1
  87. package/dist-standalone/cjs/errors.js +913 -1
  88. package/dist-standalone/cjs/event-emitter.js +461 -1
  89. package/dist-standalone/cjs/gateway-state.js +55 -1
  90. package/dist-standalone/cjs/gateway-transport.js +120 -1
  91. package/dist-standalone/cjs/graceful-degradation.js +403 -1
  92. package/dist-standalone/cjs/guardrails.js +223 -1
  93. package/dist-standalone/cjs/health-check.js +336 -1
  94. package/dist-standalone/cjs/http-compat.js +272 -1
  95. package/dist-standalone/cjs/http-status-map.js +571 -1
  96. package/dist-standalone/cjs/identity.js +645 -1
  97. package/dist-standalone/cjs/index.js +406 -1
  98. package/dist-standalone/cjs/invitation.js +421 -1
  99. package/dist-standalone/cjs/invite.js +328 -1
  100. package/dist-standalone/cjs/key-agreement.js +335 -1
  101. package/dist-standalone/cjs/lazy-init.js +300 -1
  102. package/dist-standalone/cjs/logger.js +291 -1
  103. package/dist-standalone/cjs/mdns-discovery.js +202 -1
  104. package/dist-standalone/cjs/nonce-store.js +80 -1
  105. package/dist-standalone/cjs/pairing-manager.js +223 -1
  106. package/dist-standalone/cjs/plugin-system.js +264 -1
  107. package/dist-standalone/cjs/plugins/logging.js +168 -1
  108. package/dist-standalone/cjs/plugins/metrics.js +181 -1
  109. package/dist-standalone/cjs/plugins/validation.js +302 -1
  110. package/dist-standalone/cjs/policy.js +320 -1
  111. package/dist-standalone/cjs/progress-callbacks.js +583 -1
  112. package/dist-standalone/cjs/redis-nonce-store.js +76 -1
  113. package/dist-standalone/cjs/registry-middleware.js +50 -1
  114. package/dist-standalone/cjs/retry-strategies.js +544 -1
  115. package/dist-standalone/cjs/retry-transport.js +102 -1
  116. package/dist-standalone/cjs/runtime/browser.js +533 -1
  117. package/dist-standalone/cjs/runtime/edge.js +526 -1
  118. package/dist-standalone/cjs/runtime/react-native.js +394 -1
  119. package/dist-standalone/cjs/security-policy.js +245 -1
  120. package/dist-standalone/cjs/serialization.js +1040 -1
  121. package/dist-standalone/cjs/split-channel.js +225 -1
  122. package/dist-standalone/cjs/subscription-proof.js +230 -1
  123. package/dist-standalone/cjs/succession.js +148 -1
  124. package/dist-standalone/cjs/timeouts.js +412 -1
  125. package/dist-standalone/cjs/trace-context.js +424 -1
  126. package/dist-standalone/cjs/trace-spans.js +495 -1
  127. package/dist-standalone/cjs/transport.js +63 -1
  128. package/dist-standalone/cjs/trust-registry.js +991 -1
  129. package/dist-standalone/cjs/types/error-response.js +56 -1
  130. package/dist-standalone/cjs/vault-auth.js +178 -1
  131. package/dist-standalone/cjs/vault-store-loader.js +194 -1
  132. package/dist-standalone/cjs/verify.js +25 -1
  133. package/dist-standalone/cjs/version-info.js +543 -1
  134. package/dist-standalone/cjs/xfetch.js +340 -1
  135. package/dist-standalone/cli/init.js +455 -1
  136. package/dist-standalone/cli/setup.js +514 -1
  137. package/dist-standalone/cli/types.js +27 -1
  138. package/dist-standalone/cli/xbind.js +148 -1
  139. package/dist-standalone/config-validation.js +513 -1
  140. package/dist-standalone/connect.js +274 -1
  141. package/dist-standalone/connection-pool.js +500 -1
  142. package/dist-standalone/correlation-id.js +326 -1
  143. package/dist-standalone/crypto-utils.js +157 -1
  144. package/dist-standalone/debug-mode.js +510 -1
  145. package/dist-standalone/did-document.js +96 -1
  146. package/dist-standalone/did-privateme.js +121 -1
  147. package/dist-standalone/did-web.js +196 -1
  148. package/dist-standalone/discovery.js +458 -1
  149. package/dist-standalone/dual-mode.js +247 -1
  150. package/dist-standalone/email-templates.js +309 -1
  151. package/dist-standalone/email-transport.js +232 -1
  152. package/dist-standalone/envelope.js +525 -1
  153. package/dist-standalone/errors.js +896 -1
  154. package/dist-standalone/event-emitter.js +456 -1
  155. package/dist-standalone/gateway-state.js +51 -1
  156. package/dist-standalone/gateway-transport.js +116 -1
  157. package/dist-standalone/graceful-degradation.js +396 -1
  158. package/dist-standalone/guardrails.js +216 -1
  159. package/dist-standalone/health-check.js +332 -1
  160. package/dist-standalone/http-compat.js +267 -1
  161. package/dist-standalone/http-status-map.js +561 -1
  162. package/dist-standalone/identity.js +619 -1
  163. package/dist-standalone/index.js +78 -1
  164. package/dist-standalone/invitation.js +415 -1
  165. package/dist-standalone/invite.js +324 -1
  166. package/dist-standalone/key-agreement.js +325 -1
  167. package/dist-standalone/lazy-init.js +295 -1
  168. package/dist-standalone/logger.js +285 -1
  169. package/dist-standalone/mdns-discovery.js +195 -1
  170. package/dist-standalone/nonce-store.js +76 -1
  171. package/dist-standalone/pairing-manager.js +219 -1
  172. package/dist-standalone/plugin-system.js +257 -1
  173. package/dist-standalone/plugins/logging.d.ts +84 -0
  174. package/dist-standalone/plugins/logging.js +163 -0
  175. package/dist-standalone/plugins/metrics.d.ts +111 -0
  176. package/dist-standalone/plugins/metrics.js +176 -0
  177. package/dist-standalone/plugins/validation.d.ts +104 -0
  178. package/dist-standalone/plugins/validation.js +297 -0
  179. package/dist-standalone/policy.js +315 -1
  180. package/dist-standalone/progress-callbacks.js +576 -1
  181. package/dist-standalone/redis-nonce-store.js +72 -1
  182. package/dist-standalone/registry-middleware.js +47 -1
  183. package/dist-standalone/retry-strategies.js +534 -1
  184. package/dist-standalone/retry-transport.js +98 -1
  185. package/dist-standalone/runtime/browser.d.ts +311 -0
  186. package/dist-standalone/runtime/browser.js +516 -0
  187. package/dist-standalone/runtime/edge.d.ts +282 -0
  188. package/dist-standalone/runtime/edge.js +511 -0
  189. package/dist-standalone/runtime/react-native.d.ts +157 -0
  190. package/dist-standalone/runtime/react-native.js +383 -0
  191. package/dist-standalone/security-policy.js +239 -1
  192. package/dist-standalone/serialization.js +1031 -1
  193. package/dist-standalone/split-channel.js +219 -1
  194. package/dist-standalone/subscription-proof.js +224 -1
  195. package/dist-standalone/succession.js +142 -1
  196. package/dist-standalone/timeouts.js +398 -1
  197. package/dist-standalone/trace-context.js +414 -1
  198. package/dist-standalone/trace-spans.js +488 -1
  199. package/dist-standalone/transport.js +59 -1
  200. package/dist-standalone/trust-registry.js +950 -1
  201. package/dist-standalone/types/error-response.d.ts +209 -0
  202. package/dist-standalone/types/error-response.js +52 -0
  203. package/dist-standalone/vault-auth.js +174 -1
  204. package/dist-standalone/vault-store-loader.js +187 -1
  205. package/dist-standalone/verify.js +16 -1
  206. package/dist-standalone/version-info.js +530 -1
  207. package/dist-standalone/xfetch.js +335 -1
  208. package/package.json +4 -10
  209. package/share1.dat +0 -0
  210. package/dist-standalone/_deps/mldsa-wasm/LICENSE +0 -24
  211. package/dist-standalone/_deps/mldsa-wasm/package.json +0 -46
  212. package/dist-standalone/_deps/shared/cjs/package.json +0 -1
  213. package/dist-standalone/_deps/ux-helpers/cjs/package.json +0 -1
  214. package/dist-standalone/_deps/xchange/cjs/package.json +0 -1
  215. package/dist-standalone/_deps/xregistry/cjs/package.json +0 -1
  216. package/dist-standalone/cjs/package.json +0 -3
  217. package/dist-standalone/package.json +0 -10
@@ -1 +1,388 @@
1
- import{err}from"./_deps/shared/index.js";import{ProgressReporter}from"./_deps/ux-helpers/index.js";export class BatchOperationError extends Error{summary;constructor(e,t){super(e),this.summary=t,this.name="BatchOperationError"}}export async function batchSend(e,t){const n=new ProgressReporter(t.onProgress),r=Date.now(),{messages:o,strategy:s="parallel",concurrency:a=10,continueOnError:c=!0}=t;n.start(`Sending ${o.length} messages (${s} mode)...`);const i=[];if("sequential"===s)for(let t=0;t<o.length;t++){const r=o[t],s=Date.now();n.update(`Sending message ${t+1}/${o.length}...`,t/o.length*100);const a=await e.send(r),u=Date.now()-s;if(i.push({index:t,result:a,durationMs:u}),!c&&!a.ok)break}else if("failfast"===s){const t=o.map((t,n)=>{const o=Date.now();return e.send(t).then(e=>{const t=Date.now()-o;if(!e.ok)throw new BatchOperationError(`Batch send failed at index ${n}: ${e.error}`,createSummary(i,Date.now()-r));return{index:n,result:e,durationMs:t}})});try{const e=await Promise.all(t);i.push(...e)}catch(e){if(e instanceof BatchOperationError)throw e;throw new BatchOperationError("Batch send failed",createSummary(i,Date.now()-r))}}else{const t=chunkArray(o,a);for(let r=0;r<t.length;r++){const o=t[r],s=r*a;n.update(`Processing chunk ${r+1}/${t.length}...`,r/t.length*100);const c=await Promise.all(o.map(async(t,n)=>{const r=s+n,o=Date.now();return{index:r,result:await e.send(t),durationMs:Date.now()-o}}));i.push(...c)}}return n.complete(),createSummary(i,Date.now()-r)}export async function batchReceive(e,t){const n=new ProgressReporter(t.onProgress),r=Date.now(),{envelopes:o,receiveOptions:s,strategy:a="parallel",concurrency:c=10,continueOnError:i=!0}=t;n.start(`Receiving ${o.length} envelopes (${a} mode)...`);const u=[];if("sequential"===a)for(let t=0;t<o.length;t++){const r=o[t],a=Date.now();n.update(`Receiving envelope ${t+1}/${o.length}...`,t/o.length*100);const c=await e.receive(r,s),l=Date.now()-a;if(u.push({index:t,result:c,durationMs:l}),!i&&!c.ok)break}else{const t=chunkArray(o,c);for(let r=0;r<t.length;r++){const o=t[r],a=r*c;n.update(`Processing chunk ${r+1}/${t.length}...`,r/t.length*100);const i=await Promise.all(o.map(async(t,n)=>{const r=a+n,o=Date.now();return{index:r,result:await e.receive(t,s),durationMs:Date.now()-o}}));u.push(...i)}}return n.complete(),createSummary(u,Date.now()-r)}export async function batchRegistryOps(e,t){const n=new ProgressReporter(t.onProgress),r=Date.now(),{operations:o,atomic:s=!1,strategy:a="parallel",concurrency:c=5}=t;n.start(`Executing ${o.length} registry operations (${s?"atomic":"best-effort"} mode)...`);const i=[];if(s&&n.update("Warning: Atomic mode not fully implemented - using best-effort",10),"sequential"===a)for(let t=0;t<o.length;t++){const r=o[t],a=Date.now();n.update(`Operation ${t+1}/${o.length}: ${r.type} ${r.did}`,t/o.length*100);const c=await executeRegistryOperation(e,r),u=Date.now()-a;if(i.push({index:t,result:c,durationMs:u}),s&&!c.ok)break}else{const t=chunkArray(o,c);for(let r=0;r<t.length;r++){const o=t[r],a=r*c;n.update(`Processing chunk ${r+1}/${t.length}...`,r/t.length*100);const u=await Promise.all(o.map(async(t,n)=>{const r=a+n,o=Date.now();return{index:r,result:await executeRegistryOperation(e,t),durationMs:Date.now()-o}}));if(i.push(...u),s&&u.some(e=>!e.result.ok))break}}return n.complete(),createSummary(i,Date.now()-r)}export async function batchResolve(e,t,n){const r=new ProgressReporter(n?.onProgress),o=Date.now(),s=n?.concurrency??10;r.start(`Resolving ${t.length} DIDs...`);const a=[],c=chunkArray(t,s);for(let t=0;t<c.length;t++){const n=c[t],o=t*s;r.update(`Resolving chunk ${t+1}/${c.length}...`,t/c.length*100);const i=await Promise.all(n.map(async(t,n)=>{const r=o+n,s=Date.now();return{index:r,result:await e.resolve(t),durationMs:Date.now()-s}}));a.push(...i)}return r.complete(),createSummary(a,Date.now()-o)}export async function batchGetEntries(e,t,n){const r=new ProgressReporter(n?.onProgress),o=Date.now(),s=n?.concurrency??10;r.start(`Fetching ${t.length} registry entries...`);const a=[],c=chunkArray(t,s);for(let t=0;t<c.length;t++){const n=c[t],o=t*s;r.update(`Fetching chunk ${t+1}/${c.length}...`,t/c.length*100);const i=await Promise.all(n.map(async(t,n)=>{const r=o+n,s=Date.now();return{index:r,result:await e.getEntry(t),durationMs:Date.now()-s}}));a.push(...i)}return r.complete(),createSummary(a,Date.now()-o)}async function executeRegistryOperation(e,t){switch(t.type){case"register":{if(!t.params)return err("INVALID_PARAMS");const{publicKey:n,name:r,scopes:o,x25519PublicKey:s,mlKemPublicKey:a,mlDsaPublicKey:c,xchange:i,receiveScopes:u,sdkVersion:l,minEnvelopeVersion:p,maxEnvelopeVersion:h,ttlMs:g}=t.params;return e.register(t.did,n,r,o,s,a,c,i,u,l,p,h,g)}case"revoke":return e.revoke(t.did);case"updateScopes":return t.newScopes&&"updateScopes"in e&&"function"==typeof e.updateScopes?e.updateScopes(t.did,t.newScopes):err("INVALID_PARAMS");default:return err("INVALID_OPERATION")}}function createSummary(e,t){const n=e.filter(e=>e.result.ok).length,r=e.filter(e=>!e.result.ok).length,o=e.length>0?e.reduce((e,t)=>e+t.durationMs,0)/e.length:0;return{total:e.length,succeeded:n,failed:r,results:e,totalDurationMs:t,avgDurationMs:o}}function chunkArray(e,t){const n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n}
1
+ /**
2
+ * @module batch-operations
3
+ * Batch operations support for xBind - enhanced API efficiency
4
+ *
5
+ * Provides batch operations for:
6
+ * - Send: Multiple messages in one call (reduces round-trips)
7
+ * - Receive: Batch envelope processing
8
+ * - Registry: Bulk registration/revocation/updates
9
+ *
10
+ * Features:
11
+ * - Atomic semantics where possible (registry operations)
12
+ * - Partial success handling (graceful degradation)
13
+ * - Progress tracking for long-running batches
14
+ * - Performance optimization (parallel processing)
15
+ */
16
+ import { err } from"./_deps/shared/index.js";
17
+ import { ProgressReporter } from"./_deps/ux-helpers/index.js";
18
+ /**
19
+ * Error thrown when batch operation fails.
20
+ */
21
+ export class BatchOperationError extends Error {
22
+ summary;
23
+ constructor(message, summary) {
24
+ super(message);
25
+ this.summary = summary;
26
+ this.name = 'BatchOperationError';
27
+ }
28
+ }
29
+ /* ── Implementation ── */
30
+ /**
31
+ * Batch send multiple messages.
32
+ *
33
+ * Performance optimization: Sends messages in parallel (default) or sequentially.
34
+ * Reduces round-trips for bulk message delivery.
35
+ *
36
+ * @param agent - Agent instance
37
+ * @param options - Batch send options
38
+ * @returns Batch summary with individual results
39
+ *
40
+ * @example
41
+ * ```typescript
42
+ * const agent = await Agent.create({ name: 'sender', registry });
43
+ * const summary = await batchSend(agent, {
44
+ * messages: [
45
+ * { to: 'did:key:abc', payload: { msg: 1 }, scope: 'chat' },
46
+ * { to: 'did:key:def', payload: { msg: 2 }, scope: 'chat' },
47
+ * ],
48
+ * strategy: 'parallel',
49
+ * });
50
+ * console.log(`Sent ${summary.succeeded}/${summary.total} messages`);
51
+ * ```
52
+ */
53
+ export async function batchSend(agent, options) {
54
+ const progress = new ProgressReporter(options.onProgress);
55
+ const startTime = Date.now();
56
+ const { messages, strategy = 'parallel', concurrency = 10, continueOnError = true, } = options;
57
+ progress.start(`Sending ${messages.length} messages (${strategy} mode)...`);
58
+ const results = [];
59
+ if (strategy === 'sequential') {
60
+ // Sequential: preserve ordering
61
+ for (let i = 0; i < messages.length; i++) {
62
+ const msg = messages[i];
63
+ const opStart = Date.now();
64
+ progress.update(`Sending message ${i + 1}/${messages.length}...`, (i / messages.length) * 100);
65
+ const result = await agent.send(msg);
66
+ const durationMs = Date.now() - opStart;
67
+ results.push({ index: i, result, durationMs });
68
+ if (!continueOnError && !result.ok) {
69
+ break;
70
+ }
71
+ }
72
+ }
73
+ else if (strategy === 'failfast') {
74
+ // Parallel with fail-fast: stop immediately on first error
75
+ const promises = messages.map((msg, index) => {
76
+ const opStart = Date.now();
77
+ return agent.send(msg).then(result => {
78
+ const durationMs = Date.now() - opStart;
79
+ if (!result.ok) {
80
+ throw new BatchOperationError(`Batch send failed at index ${index}: ${result.error}`, createSummary(results, Date.now() - startTime));
81
+ }
82
+ return { index, result, durationMs };
83
+ });
84
+ });
85
+ try {
86
+ const allResults = await Promise.all(promises);
87
+ results.push(...allResults);
88
+ }
89
+ catch (error) {
90
+ if (error instanceof BatchOperationError) {
91
+ throw error;
92
+ }
93
+ throw new BatchOperationError('Batch send failed', createSummary(results, Date.now() - startTime));
94
+ }
95
+ }
96
+ else {
97
+ // Parallel: process concurrently with controlled concurrency
98
+ const chunks = chunkArray(messages, concurrency);
99
+ for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
100
+ const chunk = chunks[chunkIndex];
101
+ const baseIndex = chunkIndex * concurrency;
102
+ progress.update(`Processing chunk ${chunkIndex + 1}/${chunks.length}...`, (chunkIndex / chunks.length) * 100);
103
+ const chunkResults = await Promise.all(chunk.map(async (msg, offset) => {
104
+ const index = baseIndex + offset;
105
+ const opStart = Date.now();
106
+ const result = await agent.send(msg);
107
+ const durationMs = Date.now() - opStart;
108
+ return { index, result, durationMs };
109
+ }));
110
+ results.push(...chunkResults);
111
+ }
112
+ }
113
+ progress.complete();
114
+ return createSummary(results, Date.now() - startTime);
115
+ }
116
+ /**
117
+ * Batch receive multiple envelopes.
118
+ *
119
+ * Performance optimization: Processes envelopes in parallel (default).
120
+ * Useful for bulk message ingestion from queues or webhooks.
121
+ *
122
+ * @param agent - Agent instance
123
+ * @param options - Batch receive options
124
+ * @returns Batch summary with individual results
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * const agent = await Agent.create({ name: 'receiver', registry });
129
+ * const summary = await batchReceive(agent, {
130
+ * envelopes: incomingEnvelopes,
131
+ * strategy: 'parallel',
132
+ * });
133
+ * console.log(`Processed ${summary.succeeded}/${summary.total} envelopes`);
134
+ * ```
135
+ */
136
+ export async function batchReceive(agent, options) {
137
+ const progress = new ProgressReporter(options.onProgress);
138
+ const startTime = Date.now();
139
+ const { envelopes, receiveOptions, strategy = 'parallel', concurrency = 10, continueOnError = true, } = options;
140
+ progress.start(`Receiving ${envelopes.length} envelopes (${strategy} mode)...`);
141
+ const results = [];
142
+ if (strategy === 'sequential') {
143
+ // Sequential: preserve ordering
144
+ for (let i = 0; i < envelopes.length; i++) {
145
+ const envelope = envelopes[i];
146
+ const opStart = Date.now();
147
+ progress.update(`Receiving envelope ${i + 1}/${envelopes.length}...`, (i / envelopes.length) * 100);
148
+ const result = await agent.receive(envelope, receiveOptions);
149
+ const durationMs = Date.now() - opStart;
150
+ results.push({ index: i, result, durationMs });
151
+ if (!continueOnError && !result.ok) {
152
+ break;
153
+ }
154
+ }
155
+ }
156
+ else {
157
+ // Parallel: process concurrently with controlled concurrency
158
+ const chunks = chunkArray(envelopes, concurrency);
159
+ for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
160
+ const chunk = chunks[chunkIndex];
161
+ const baseIndex = chunkIndex * concurrency;
162
+ progress.update(`Processing chunk ${chunkIndex + 1}/${chunks.length}...`, (chunkIndex / chunks.length) * 100);
163
+ const chunkResults = await Promise.all(chunk.map(async (envelope, offset) => {
164
+ const index = baseIndex + offset;
165
+ const opStart = Date.now();
166
+ const result = await agent.receive(envelope, receiveOptions);
167
+ const durationMs = Date.now() - opStart;
168
+ return { index, result, durationMs };
169
+ }));
170
+ results.push(...chunkResults);
171
+ }
172
+ }
173
+ progress.complete();
174
+ return createSummary(results, Date.now() - startTime);
175
+ }
176
+ /**
177
+ * Batch registry operations (register, revoke, updateScopes).
178
+ *
179
+ * Performance optimization: Groups operations by type for efficient processing.
180
+ * Atomic semantics: When atomic=true, all operations succeed or all fail.
181
+ *
182
+ * @param registry - Trust registry instance
183
+ * @param options - Batch registry options
184
+ * @returns Batch summary with individual results
185
+ *
186
+ * @example
187
+ * ```typescript
188
+ * const summary = await batchRegistryOps(registry, {
189
+ * operations: [
190
+ * { type: 'register', did: 'did:key:abc', params: { publicKey, name: 'Alice' } },
191
+ * { type: 'revoke', did: 'did:key:old' },
192
+ * ],
193
+ * atomic: false, // best-effort mode
194
+ * });
195
+ * console.log(`Completed ${summary.succeeded}/${summary.total} operations`);
196
+ * ```
197
+ */
198
+ export async function batchRegistryOps(registry, options) {
199
+ const progress = new ProgressReporter(options.onProgress);
200
+ const startTime = Date.now();
201
+ const { operations, atomic = false, strategy = 'parallel', concurrency = 5, } = options;
202
+ progress.start(`Executing ${operations.length} registry operations (${atomic ? 'atomic' : 'best-effort'} mode)...`);
203
+ const results = [];
204
+ // Atomic mode: execute all or rollback (not implemented in base TrustRegistry)
205
+ // This is a placeholder for future transaction support
206
+ if (atomic) {
207
+ progress.update('Warning: Atomic mode not fully implemented - using best-effort', 10);
208
+ }
209
+ if (strategy === 'sequential') {
210
+ // Sequential: preserve ordering
211
+ for (let i = 0; i < operations.length; i++) {
212
+ const op = operations[i];
213
+ const opStart = Date.now();
214
+ progress.update(`Operation ${i + 1}/${operations.length}: ${op.type} ${op.did}`, (i / operations.length) * 100);
215
+ const result = await executeRegistryOperation(registry, op);
216
+ const durationMs = Date.now() - opStart;
217
+ results.push({ index: i, result, durationMs });
218
+ if (atomic && !result.ok) {
219
+ // TODO: Rollback previous operations
220
+ break;
221
+ }
222
+ }
223
+ }
224
+ else {
225
+ // Parallel: process concurrently with controlled concurrency
226
+ const chunks = chunkArray(operations, concurrency);
227
+ for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
228
+ const chunk = chunks[chunkIndex];
229
+ const baseIndex = chunkIndex * concurrency;
230
+ progress.update(`Processing chunk ${chunkIndex + 1}/${chunks.length}...`, (chunkIndex / chunks.length) * 100);
231
+ const chunkResults = await Promise.all(chunk.map(async (op, offset) => {
232
+ const index = baseIndex + offset;
233
+ const opStart = Date.now();
234
+ const result = await executeRegistryOperation(registry, op);
235
+ const durationMs = Date.now() - opStart;
236
+ return { index, result, durationMs };
237
+ }));
238
+ results.push(...chunkResults);
239
+ if (atomic && chunkResults.some(r => !r.result.ok)) {
240
+ // TODO: Rollback all operations
241
+ break;
242
+ }
243
+ }
244
+ }
245
+ progress.complete();
246
+ return createSummary(results, Date.now() - startTime);
247
+ }
248
+ /**
249
+ * Batch resolve multiple DIDs.
250
+ *
251
+ * Performance optimization: Resolves DIDs in parallel.
252
+ * Useful for resolving recipient keys before bulk message sending.
253
+ *
254
+ * @param registry - Trust registry instance
255
+ * @param dids - DIDs to resolve
256
+ * @param options - Optional progress callback and concurrency
257
+ * @returns Batch summary with resolution results
258
+ *
259
+ * @example
260
+ * ```typescript
261
+ * const summary = await batchResolve(registry, [
262
+ * 'did:key:abc',
263
+ * 'did:key:def',
264
+ * 'did:key:ghi',
265
+ * ]);
266
+ * const keys = summary.results
267
+ * .filter(r => r.result.ok)
268
+ * .map(r => r.result.value);
269
+ * ```
270
+ */
271
+ export async function batchResolve(registry, dids, options) {
272
+ const progress = new ProgressReporter(options?.onProgress);
273
+ const startTime = Date.now();
274
+ const concurrency = options?.concurrency ?? 10;
275
+ progress.start(`Resolving ${dids.length} DIDs...`);
276
+ const results = [];
277
+ const chunks = chunkArray(dids, concurrency);
278
+ for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
279
+ const chunk = chunks[chunkIndex];
280
+ const baseIndex = chunkIndex * concurrency;
281
+ progress.update(`Resolving chunk ${chunkIndex + 1}/${chunks.length}...`, (chunkIndex / chunks.length) * 100);
282
+ const chunkResults = await Promise.all(chunk.map(async (did, offset) => {
283
+ const index = baseIndex + offset;
284
+ const opStart = Date.now();
285
+ const result = await registry.resolve(did);
286
+ const durationMs = Date.now() - opStart;
287
+ return { index, result, durationMs };
288
+ }));
289
+ results.push(...chunkResults);
290
+ }
291
+ progress.complete();
292
+ return createSummary(results, Date.now() - startTime);
293
+ }
294
+ /**
295
+ * Batch get registry entries.
296
+ *
297
+ * Performance optimization: Fetches entries in parallel.
298
+ * Returns full registry metadata for multiple DIDs.
299
+ *
300
+ * @param registry - Trust registry instance
301
+ * @param dids - DIDs to fetch
302
+ * @param options - Optional progress callback and concurrency
303
+ * @returns Batch summary with entry results
304
+ *
305
+ * @example
306
+ * ```typescript
307
+ * const summary = await batchGetEntries(registry, dids);
308
+ * const entries = summary.results
309
+ * .filter(r => r.result.ok)
310
+ * .map(r => r.result.value);
311
+ * ```
312
+ */
313
+ export async function batchGetEntries(registry, dids, options) {
314
+ const progress = new ProgressReporter(options?.onProgress);
315
+ const startTime = Date.now();
316
+ const concurrency = options?.concurrency ?? 10;
317
+ progress.start(`Fetching ${dids.length} registry entries...`);
318
+ const results = [];
319
+ const chunks = chunkArray(dids, concurrency);
320
+ for (let chunkIndex = 0; chunkIndex < chunks.length; chunkIndex++) {
321
+ const chunk = chunks[chunkIndex];
322
+ const baseIndex = chunkIndex * concurrency;
323
+ progress.update(`Fetching chunk ${chunkIndex + 1}/${chunks.length}...`, (chunkIndex / chunks.length) * 100);
324
+ const chunkResults = await Promise.all(chunk.map(async (did, offset) => {
325
+ const index = baseIndex + offset;
326
+ const opStart = Date.now();
327
+ const result = await registry.getEntry(did);
328
+ const durationMs = Date.now() - opStart;
329
+ return { index, result, durationMs };
330
+ }));
331
+ results.push(...chunkResults);
332
+ }
333
+ progress.complete();
334
+ return createSummary(results, Date.now() - startTime);
335
+ }
336
+ /* ── Helper Functions ── */
337
+ /**
338
+ * Execute a single registry operation.
339
+ */
340
+ async function executeRegistryOperation(registry, op) {
341
+ switch (op.type) {
342
+ case 'register': {
343
+ if (!op.params) {
344
+ return err('INVALID_PARAMS');
345
+ }
346
+ const { publicKey, name, scopes, x25519PublicKey, mlKemPublicKey, mlDsaPublicKey, xchange, receiveScopes, sdkVersion, minEnvelopeVersion, maxEnvelopeVersion, ttlMs } = op.params;
347
+ return registry.register(op.did, publicKey, name, scopes, x25519PublicKey, mlKemPublicKey, mlDsaPublicKey, xchange, receiveScopes, sdkVersion, minEnvelopeVersion, maxEnvelopeVersion, ttlMs);
348
+ }
349
+ case 'revoke':
350
+ return registry.revoke(op.did);
351
+ case 'updateScopes': {
352
+ if (!op.newScopes || !('updateScopes' in registry) || typeof registry.updateScopes !== 'function') {
353
+ return err('INVALID_PARAMS');
354
+ }
355
+ return registry.updateScopes(op.did, op.newScopes);
356
+ }
357
+ default:
358
+ return err('INVALID_OPERATION');
359
+ }
360
+ }
361
+ /**
362
+ * Create batch summary from results.
363
+ */
364
+ function createSummary(results, totalDurationMs) {
365
+ const succeeded = results.filter(r => r.result.ok).length;
366
+ const failed = results.filter(r => !r.result.ok).length;
367
+ const avgDurationMs = results.length > 0
368
+ ? results.reduce((sum, r) => sum + r.durationMs, 0) / results.length
369
+ : 0;
370
+ return {
371
+ total: results.length,
372
+ succeeded,
373
+ failed,
374
+ results,
375
+ totalDurationMs,
376
+ avgDurationMs,
377
+ };
378
+ }
379
+ /**
380
+ * Split array into chunks of specified size.
381
+ */
382
+ function chunkArray(array, size) {
383
+ const chunks = [];
384
+ for (let i = 0; i < array.length; i += size) {
385
+ chunks.push(array.slice(i, i + size));
386
+ }
387
+ return chunks;
388
+ }