@private.me/xbind 3.0.2 → 3.0.3

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 (221) hide show
  1. package/README.md +2366 -204
  2. package/README.md.backup +2121 -0
  3. package/dist-standalone/_deps/mldsa-wasm/dist/mldsa.js +1 -1920
  4. package/dist-standalone/_deps/shared/cjs/errors.js +1 -729
  5. package/dist-standalone/_deps/shared/cjs/index.js +1 -463
  6. package/dist-standalone/_deps/shared/cjs/types.js +1 -315
  7. package/dist-standalone/_deps/shared/errors.js +1 -244
  8. package/dist-standalone/_deps/shared/index.js +1 -72
  9. package/dist-standalone/_deps/shared/types.js +1 -86
  10. package/dist-standalone/_deps/ux-helpers/cjs/errors.js +1 -1
  11. package/dist-standalone/_deps/ux-helpers/cjs/index.js +1 -1
  12. package/dist-standalone/_deps/ux-helpers/cjs/pagination.js +1 -1
  13. package/dist-standalone/_deps/ux-helpers/cjs/progress.js +1 -1
  14. package/dist-standalone/_deps/ux-helpers/cjs/search.js +1 -1
  15. package/dist-standalone/_deps/ux-helpers/cjs/types.js +1 -1
  16. package/dist-standalone/_deps/ux-helpers/errors.js +1 -1
  17. package/dist-standalone/_deps/ux-helpers/index.js +1 -1
  18. package/dist-standalone/_deps/ux-helpers/pagination.js +1 -1
  19. package/dist-standalone/_deps/ux-helpers/progress.js +1 -1
  20. package/dist-standalone/_deps/ux-helpers/search.js +1 -1
  21. package/dist-standalone/_deps/xchange/auto-accept.js +1 -1
  22. package/dist-standalone/_deps/xchange/cjs/auto-accept.js +1 -1
  23. package/dist-standalone/_deps/xchange/cjs/errors.js +1 -1
  24. package/dist-standalone/_deps/xchange/cjs/index.js +1 -1
  25. package/dist-standalone/_deps/xchange/cjs/invite-client.js +1 -1
  26. package/dist-standalone/_deps/xchange/cjs/lazy-init.js +1 -1
  27. package/dist-standalone/_deps/xchange/cjs/trust-integration.js +1 -1
  28. package/dist-standalone/_deps/xchange/cjs/xchange.js +1 -1
  29. package/dist-standalone/_deps/xchange/errors.js +1 -1
  30. package/dist-standalone/_deps/xchange/index.js +1 -1
  31. package/dist-standalone/_deps/xchange/invite-client.js +1 -1
  32. package/dist-standalone/_deps/xchange/lazy-init.js +1 -1
  33. package/dist-standalone/_deps/xchange/trust-integration.js +1 -1
  34. package/dist-standalone/_deps/xchange/xchange.js +1 -1
  35. package/dist-standalone/_deps/xregistry/cjs/discovery.js +1 -1
  36. package/dist-standalone/_deps/xregistry/cjs/errors.js +1 -1
  37. package/dist-standalone/_deps/xregistry/cjs/index.js +1 -1
  38. package/dist-standalone/_deps/xregistry/cjs/registry.js +1 -1
  39. package/dist-standalone/_deps/xregistry/cjs/schema.js +1 -1
  40. package/dist-standalone/_deps/xregistry/cjs/types.js +1 -1
  41. package/dist-standalone/_deps/xregistry/discovery.js +1 -1
  42. package/dist-standalone/_deps/xregistry/errors.js +1 -1
  43. package/dist-standalone/_deps/xregistry/index.js +1 -1
  44. package/dist-standalone/_deps/xregistry/registry.js +1 -1
  45. package/dist-standalone/_deps/xregistry/schema.js +1 -1
  46. package/dist-standalone/_deps/xregistry/types.js +1 -1
  47. package/dist-standalone/agent-call.d.ts +2 -2
  48. package/dist-standalone/agent-call.js +1 -659
  49. package/dist-standalone/agent-sdk.js +1 -328
  50. package/dist-standalone/agent.d.ts +2 -0
  51. package/dist-standalone/agent.js +1 -1800
  52. package/dist-standalone/approval.js +1 -193
  53. package/dist-standalone/async-iterators.d.ts +3 -3
  54. package/dist-standalone/async-iterators.js +1 -382
  55. package/dist-standalone/auth.js +1 -219
  56. package/dist-standalone/auto-accept.js +1 -229
  57. package/dist-standalone/backup-config.js +1 -201
  58. package/dist-standalone/backup.js +1 -326
  59. package/dist-standalone/batch-operations.js +1 -388
  60. package/dist-standalone/cancellation.js +1 -477
  61. package/dist-standalone/checkpoint.js +1 -186
  62. package/dist-standalone/circuit-breaker.js +1 -468
  63. package/dist-standalone/cjs/agent-call.js +1 -701
  64. package/dist-standalone/cjs/agent-sdk.js +1 -332
  65. package/dist-standalone/cjs/agent.js +1 -1837
  66. package/dist-standalone/cjs/approval.js +1 -199
  67. package/dist-standalone/cjs/async-iterators.js +1 -392
  68. package/dist-standalone/cjs/auth.js +1 -225
  69. package/dist-standalone/cjs/auto-accept.js +1 -233
  70. package/dist-standalone/cjs/backup-config.js +1 -207
  71. package/dist-standalone/cjs/backup.js +1 -330
  72. package/dist-standalone/cjs/batch-operations.js +1 -397
  73. package/dist-standalone/cjs/cancellation.js +1 -490
  74. package/dist-standalone/cjs/checkpoint.js +1 -193
  75. package/dist-standalone/cjs/circuit-breaker.js +1 -476
  76. package/dist-standalone/cjs/cli/init.js +1 -492
  77. package/dist-standalone/cjs/config-validation.js +1 -522
  78. package/dist-standalone/cjs/connect.js +1 -312
  79. package/dist-standalone/cjs/connection-pool.js +1 -506
  80. package/dist-standalone/cjs/correlation-id.js +1 -339
  81. package/dist-standalone/cjs/crypto-utils.js +1 -176
  82. package/dist-standalone/cjs/debug-mode.js +1 -534
  83. package/dist-standalone/cjs/did-document.js +1 -101
  84. package/dist-standalone/cjs/did-privateme.js +1 -130
  85. package/dist-standalone/cjs/did-web.js +1 -201
  86. package/dist-standalone/cjs/discovery.js +1 -462
  87. package/dist-standalone/cjs/dual-mode.js +1 -251
  88. package/dist-standalone/cjs/email-templates.js +1 -313
  89. package/dist-standalone/cjs/email-transport.js +1 -239
  90. package/dist-standalone/cjs/envelope.js +1 -538
  91. package/dist-standalone/cjs/errors.js +1 -913
  92. package/dist-standalone/cjs/event-emitter.js +1 -461
  93. package/dist-standalone/cjs/gateway-state.js +1 -55
  94. package/dist-standalone/cjs/gateway-transport.js +1 -120
  95. package/dist-standalone/cjs/graceful-degradation.js +1 -403
  96. package/dist-standalone/cjs/guardrails.js +1 -223
  97. package/dist-standalone/cjs/health-check.js +1 -336
  98. package/dist-standalone/cjs/http-compat.js +1 -272
  99. package/dist-standalone/cjs/http-status-map.js +1 -571
  100. package/dist-standalone/cjs/identity.js +1 -645
  101. package/dist-standalone/cjs/index.js +1 -406
  102. package/dist-standalone/cjs/invitation.js +1 -421
  103. package/dist-standalone/cjs/invite.js +1 -328
  104. package/dist-standalone/cjs/key-agreement.js +1 -335
  105. package/dist-standalone/cjs/lazy-init.js +1 -300
  106. package/dist-standalone/cjs/logger.js +1 -291
  107. package/dist-standalone/cjs/loopback-transport.js +1 -0
  108. package/dist-standalone/cjs/mdns-discovery.js +1 -202
  109. package/dist-standalone/cjs/nonce-store.js +1 -80
  110. package/dist-standalone/cjs/pairing-manager.js +1 -223
  111. package/dist-standalone/cjs/plugin-system.js +1 -264
  112. package/dist-standalone/cjs/plugins/logging.js +1 -168
  113. package/dist-standalone/cjs/plugins/metrics.js +1 -181
  114. package/dist-standalone/cjs/plugins/validation.js +1 -302
  115. package/dist-standalone/cjs/policy.js +1 -320
  116. package/dist-standalone/cjs/progress-callbacks.js +1 -583
  117. package/dist-standalone/cjs/redis-nonce-store.js +1 -76
  118. package/dist-standalone/cjs/registry-middleware.js +1 -50
  119. package/dist-standalone/cjs/retry-strategies.js +1 -544
  120. package/dist-standalone/cjs/retry-transport.js +1 -102
  121. package/dist-standalone/cjs/runtime/browser.js +1 -533
  122. package/dist-standalone/cjs/runtime/edge.js +1 -526
  123. package/dist-standalone/cjs/runtime/react-native.js +1 -394
  124. package/dist-standalone/cjs/security-policy.js +1 -245
  125. package/dist-standalone/cjs/serialization.js +1 -1040
  126. package/dist-standalone/cjs/split-channel.js +1 -225
  127. package/dist-standalone/cjs/subscription-proof.js +1 -230
  128. package/dist-standalone/cjs/succession.js +1 -148
  129. package/dist-standalone/cjs/timeouts.js +1 -412
  130. package/dist-standalone/cjs/trace-context.js +1 -424
  131. package/dist-standalone/cjs/trace-spans.js +1 -495
  132. package/dist-standalone/cjs/transport.js +1 -63
  133. package/dist-standalone/cjs/trust-registry.js +1 -991
  134. package/dist-standalone/cjs/types/error-response.js +1 -56
  135. package/dist-standalone/cjs/vault-auth.js +1 -178
  136. package/dist-standalone/cjs/vault-store-loader.js +1 -194
  137. package/dist-standalone/cjs/verify.js +1 -25
  138. package/dist-standalone/cjs/version-info.js +1 -543
  139. package/dist-standalone/cjs/xfetch.js +1 -340
  140. package/dist-standalone/cli/init.js +1 -455
  141. package/dist-standalone/cli/setup.js +1 -514
  142. package/dist-standalone/cli/types.js +1 -27
  143. package/dist-standalone/cli/xbind.js +1 -148
  144. package/dist-standalone/config-validation.js +1 -513
  145. package/dist-standalone/connect.js +1 -274
  146. package/dist-standalone/connection-pool.js +1 -500
  147. package/dist-standalone/correlation-id.js +1 -326
  148. package/dist-standalone/crypto-utils.d.ts +2 -7
  149. package/dist-standalone/crypto-utils.js +1 -157
  150. package/dist-standalone/debug-mode.js +1 -510
  151. package/dist-standalone/did-document.js +1 -96
  152. package/dist-standalone/did-privateme.js +1 -121
  153. package/dist-standalone/did-web.js +1 -196
  154. package/dist-standalone/discovery.js +1 -458
  155. package/dist-standalone/dual-mode.js +1 -247
  156. package/dist-standalone/email-templates.js +1 -309
  157. package/dist-standalone/email-transport.d.ts +2 -2
  158. package/dist-standalone/email-transport.js +1 -232
  159. package/dist-standalone/envelope.js +1 -525
  160. package/dist-standalone/errors.d.ts +13 -3
  161. package/dist-standalone/errors.js +1 -896
  162. package/dist-standalone/event-emitter.js +1 -456
  163. package/dist-standalone/gateway-state.d.ts +1 -1
  164. package/dist-standalone/gateway-state.js +1 -51
  165. package/dist-standalone/gateway-transport.js +1 -116
  166. package/dist-standalone/graceful-degradation.js +1 -396
  167. package/dist-standalone/guardrails.js +1 -216
  168. package/dist-standalone/health-check.d.ts +5 -1
  169. package/dist-standalone/health-check.js +1 -332
  170. package/dist-standalone/http-compat.d.ts +1 -1
  171. package/dist-standalone/http-compat.js +1 -267
  172. package/dist-standalone/http-status-map.js +1 -561
  173. package/dist-standalone/identity.js +1 -619
  174. package/dist-standalone/index.d.ts +15 -4
  175. package/dist-standalone/index.js +1 -78
  176. package/dist-standalone/invitation.js +1 -415
  177. package/dist-standalone/invite.js +1 -324
  178. package/dist-standalone/key-agreement.js +1 -325
  179. package/dist-standalone/lazy-init.d.ts +11 -6
  180. package/dist-standalone/lazy-init.js +1 -295
  181. package/dist-standalone/logger.js +1 -285
  182. package/dist-standalone/loopback-transport.d.ts +87 -0
  183. package/dist-standalone/loopback-transport.js +1 -0
  184. package/dist-standalone/mdns-discovery.js +1 -195
  185. package/dist-standalone/nonce-store.js +1 -76
  186. package/dist-standalone/pairing-manager.js +1 -219
  187. package/dist-standalone/plugin-system.js +1 -257
  188. package/dist-standalone/plugins/logging.js +1 -163
  189. package/dist-standalone/plugins/metrics.d.ts +4 -4
  190. package/dist-standalone/plugins/metrics.js +1 -176
  191. package/dist-standalone/plugins/validation.js +1 -297
  192. package/dist-standalone/policy.js +1 -315
  193. package/dist-standalone/progress-callbacks.js +1 -576
  194. package/dist-standalone/redis-nonce-store.js +1 -72
  195. package/dist-standalone/registry-middleware.js +1 -47
  196. package/dist-standalone/retry-strategies.js +1 -534
  197. package/dist-standalone/retry-transport.js +1 -98
  198. package/dist-standalone/runtime/browser.js +1 -516
  199. package/dist-standalone/runtime/edge.js +1 -511
  200. package/dist-standalone/runtime/react-native.d.ts +1 -1
  201. package/dist-standalone/runtime/react-native.js +1 -383
  202. package/dist-standalone/security-policy.js +1 -239
  203. package/dist-standalone/serialization.js +1 -1031
  204. package/dist-standalone/split-channel.js +1 -219
  205. package/dist-standalone/subscription-proof.js +1 -224
  206. package/dist-standalone/succession.js +1 -142
  207. package/dist-standalone/timeouts.js +1 -398
  208. package/dist-standalone/trace-context.js +1 -414
  209. package/dist-standalone/trace-spans.js +1 -488
  210. package/dist-standalone/transport.js +1 -59
  211. package/dist-standalone/trust-registry.d.ts +3 -3
  212. package/dist-standalone/trust-registry.js +1 -950
  213. package/dist-standalone/types/error-response.js +1 -52
  214. package/dist-standalone/vault-auth.js +1 -174
  215. package/dist-standalone/vault-store-loader.d.ts +9 -0
  216. package/dist-standalone/vault-store-loader.js +1 -187
  217. package/dist-standalone/verify.js +1 -16
  218. package/dist-standalone/version-info.js +1 -530
  219. package/dist-standalone/xfetch.js +1 -335
  220. package/package.json +1 -1
  221. package/share1.dat +0 -0
@@ -1,193 +1 @@
1
- /**
2
- * @module approval
3
- * OAuth-style approval flow for agents
4
- *
5
- * Enterprise agents require explicit user consent before performing
6
- * sensitive operations. This module implements OAuth-style consent
7
- * screens and approval tokens.
8
- */
9
- import { ok, err } from"./_deps/shared/index.js";
10
- /**
11
- * Approval error codes
12
- */
13
- export var ApprovalErrorCode;
14
- (function (ApprovalErrorCode) {
15
- ApprovalErrorCode["USER_DENIED"] = "APPROVAL_USER_DENIED";
16
- ApprovalErrorCode["TIMEOUT"] = "APPROVAL_TIMEOUT";
17
- ApprovalErrorCode["INVALID_DURATION"] = "APPROVAL_INVALID_DURATION";
18
- ApprovalErrorCode["SIGNATURE_FAILED"] = "APPROVAL_SIGNATURE_FAILED";
19
- ApprovalErrorCode["TOKEN_EXPIRED"] = "APPROVAL_TOKEN_EXPIRED";
20
- ApprovalErrorCode["TOKEN_REVOKED"] = "APPROVAL_TOKEN_REVOKED";
21
- ApprovalErrorCode["INVALID_TOKEN"] = "APPROVAL_INVALID_TOKEN";
22
- })(ApprovalErrorCode || (ApprovalErrorCode = {}));
23
- /**
24
- * Approval error
25
- */
26
- export class ApprovalError extends Error {
27
- code;
28
- details;
29
- constructor(code, message, details) {
30
- super(message);
31
- this.code = code;
32
- this.details = details;
33
- this.name = 'ApprovalError';
34
- }
35
- }
36
- /**
37
- * CLI approval presenter (prints to console, reads stdin)
38
- * This is a legitimate CLI interface - console output is intentional
39
- */
40
- export class CLIApprovalPresenter {
41
- /* eslint-disable no-console */
42
- async present(options) {
43
- console.log('\n=== AGENT APPROVAL REQUEST ===');
44
- console.log(`Agent: ${options.agentDid}`);
45
- console.log(`Duration: ${options.duration}`);
46
- console.log('\nRequested Scopes:');
47
- for (const scope of options.scopes) {
48
- console.log(` - ${scope}`);
49
- }
50
- if (options.limits) {
51
- console.log('\nPolicy Limits:');
52
- if (options.limits.amountPerTxn) {
53
- console.log(` - Max per transaction: $${options.limits.amountPerTxn.toLocaleString()}`);
54
- }
55
- if (options.limits.dailyAmount) {
56
- console.log(` - Daily limit: $${options.limits.dailyAmount.toLocaleString()}`);
57
- }
58
- if (options.limits.callsPerMinute) {
59
- console.log(` - Rate limit: ${options.limits.callsPerMinute} calls/minute`);
60
- }
61
- }
62
- if (options.description) {
63
- console.log(`\nDescription: ${options.description}`);
64
- }
65
- console.log('\n[This is a mock presenter - auto-approving for development]');
66
- console.log('In production, this would prompt for user input.\n');
67
- // Auto-approve for development (production would prompt for y/n)
68
- return ok({
69
- approved: true,
70
- });
71
- }
72
- }
73
- /**
74
- * Approval flow coordinator
75
- *
76
- * Orchestrates the consent flow: present to user → sign token → track expiry
77
- */
78
- export class ApprovalFlow {
79
- presenter;
80
- tokens = new Map();
81
- constructor(options = {}) {
82
- this.presenter = options.presenter ?? new CLIApprovalPresenter();
83
- }
84
- /**
85
- * Request approval from user
86
- *
87
- * @param options - Approval request options
88
- * @returns Approval result with token (if approved)
89
- */
90
- async requestApproval(options) {
91
- // Validate duration
92
- const durationMs = this.parseDuration(options.duration);
93
- if (durationMs <= 0) {
94
- return err(new ApprovalError(ApprovalErrorCode.INVALID_DURATION, `Invalid duration: ${options.duration}`));
95
- }
96
- // Present to user
97
- const result = await this.presenter.present(options);
98
- if (!result.ok)
99
- return result;
100
- if (!result.value.approved) {
101
- return ok({
102
- approved: false,
103
- reason: result.value.reason ?? 'User denied approval',
104
- });
105
- }
106
- // Generate approval token
107
- const now = Date.now();
108
- const token = {
109
- id: this.generateTokenId(),
110
- agentDid: options.agentDid,
111
- scopes: options.scopes,
112
- limits: options.limits,
113
- expiresAt: now + durationMs,
114
- createdAt: now,
115
- valid: true,
116
- signature: await this.signToken(options.agentDid, options.scopes, now + durationMs),
117
- };
118
- // Store token
119
- this.tokens.set(token.id, token);
120
- return ok({
121
- approved: true,
122
- token,
123
- });
124
- }
125
- /**
126
- * Verify an approval token
127
- *
128
- * @param tokenId - Token ID to verify
129
- * @returns Token if valid, error otherwise
130
- */
131
- verifyToken(tokenId) {
132
- const token = this.tokens.get(tokenId);
133
- if (!token) {
134
- return err(new ApprovalError(ApprovalErrorCode.INVALID_TOKEN, `Token ${tokenId} not found`));
135
- }
136
- if (!token.valid) {
137
- return err(new ApprovalError(ApprovalErrorCode.TOKEN_REVOKED, `Token ${tokenId} has been revoked`));
138
- }
139
- if (Date.now() > token.expiresAt) {
140
- return err(new ApprovalError(ApprovalErrorCode.TOKEN_EXPIRED, `Token ${tokenId} expired at ${new Date(token.expiresAt).toISOString()}`));
141
- }
142
- return ok(token);
143
- }
144
- /**
145
- * Revoke an approval token
146
- *
147
- * @param tokenId - Token ID to revoke
148
- */
149
- revokeToken(tokenId) {
150
- const token = this.tokens.get(tokenId);
151
- if (token) {
152
- this.tokens.set(tokenId, { ...token, valid: false });
153
- }
154
- }
155
- /**
156
- * Parse duration string to milliseconds
157
- */
158
- parseDuration(duration) {
159
- if (typeof duration === 'number')
160
- return duration;
161
- // Parse ISO 8601 duration or simple format
162
- const matches = duration.match(/^(\d+)([smhd])$/);
163
- if (!matches)
164
- return -1;
165
- const value = parseInt(matches[1] ?? '0', 10);
166
- const unit = matches[2];
167
- switch (unit) {
168
- case 's': return value * 1000;
169
- case 'm': return value * 60 * 1000;
170
- case 'h': return value * 60 * 60 * 1000;
171
- case 'd': return value * 24 * 60 * 60 * 1000;
172
- default: return -1;
173
- }
174
- }
175
- /**
176
- * Generate a unique token ID
177
- */
178
- generateTokenId() {
179
- const randomBytes = new Uint8Array(12);
180
- crypto.getRandomValues(randomBytes);
181
- const randomString = Array.from(randomBytes, b => b.toString(16).padStart(2, '0')).join('');
182
- return `appr_${Date.now()}_${randomString}`;
183
- }
184
- /**
185
- * Sign an approval token (stub - production would use Ed25519)
186
- */
187
- async signToken(agentDid, scopes, expiresAt) {
188
- // Production would use Ed25519 signature over JSON.stringify({ agentDid, scopes, expiresAt })
189
- // For now, return a mock signature
190
- const payload = JSON.stringify({ agentDid, scopes, expiresAt });
191
- return btoa(payload).substring(0, 32);
192
- }
193
- }
1
+ import{ok,err}from"./_deps/shared/index.js";export var ApprovalErrorCode;!function(e){e.USER_DENIED="APPROVAL_USER_DENIED",e.TIMEOUT="APPROVAL_TIMEOUT",e.INVALID_DURATION="APPROVAL_INVALID_DURATION",e.SIGNATURE_FAILED="APPROVAL_SIGNATURE_FAILED",e.TOKEN_EXPIRED="APPROVAL_TOKEN_EXPIRED",e.TOKEN_REVOKED="APPROVAL_TOKEN_REVOKED",e.INVALID_TOKEN="APPROVAL_INVALID_TOKEN"}(ApprovalErrorCode||(ApprovalErrorCode={}));export class ApprovalError extends Error{code;details;constructor(e,r,o){super(r),this.code=e,this.details=o,this.name="ApprovalError"}}export class CLIApprovalPresenter{async present(e){console.log("\n=== AGENT APPROVAL REQUEST ==="),console.log(`Agent: ${e.agentDid}`),console.log(`Duration: ${e.duration}`),console.log("\nRequested Scopes:");for(const r of e.scopes)console.log(` - ${r}`);return e.limits&&(console.log("\nPolicy Limits:"),e.limits.amountPerTxn&&console.log(` - Max per transaction: $${e.limits.amountPerTxn.toLocaleString()}`),e.limits.dailyAmount&&console.log(` - Daily limit: $${e.limits.dailyAmount.toLocaleString()}`),e.limits.callsPerMinute&&console.log(` - Rate limit: ${e.limits.callsPerMinute} calls/minute`)),e.description&&console.log(`\nDescription: ${e.description}`),console.log("\n[This is a mock presenter - auto-approving for development]"),console.log("In production, this would prompt for user input.\n"),ok({approved:!0})}}export class ApprovalFlow{presenter;tokens=new Map;constructor(e={}){this.presenter=e.presenter??new CLIApprovalPresenter}async requestApproval(e){const r=this.parseDuration(e.duration);if(r<=0)return err(new ApprovalError(ApprovalErrorCode.INVALID_DURATION,`Invalid duration: ${e.duration}`));const o=await this.presenter.present(e);if(!o.ok)return o;if(!o.value.approved)return ok({approved:!1,reason:o.value.reason??"User denied approval"});const t=Date.now(),n={id:this.generateTokenId(),agentDid:e.agentDid,scopes:e.scopes,limits:e.limits,expiresAt:t+r,createdAt:t,valid:!0,signature:await this.signToken(e.agentDid,e.scopes,t+r)};return this.tokens.set(n.id,n),ok({approved:!0,token:n})}verifyToken(e){const r=this.tokens.get(e);return r?r.valid?Date.now()>r.expiresAt?err(new ApprovalError(ApprovalErrorCode.TOKEN_EXPIRED,`Token ${e} expired at ${new Date(r.expiresAt).toISOString()}`)):ok(r):err(new ApprovalError(ApprovalErrorCode.TOKEN_REVOKED,`Token ${e} has been revoked`)):err(new ApprovalError(ApprovalErrorCode.INVALID_TOKEN,`Token ${e} not found`))}revokeToken(e){const r=this.tokens.get(e);r&&this.tokens.set(e,{...r,valid:!1})}parseDuration(e){if("number"==typeof e)return e;const r=e.match(/^(\d+)([smhd])$/);if(!r)return-1;const o=parseInt(r[1]??"0",10);switch(r[2]){case"s":return 1e3*o;case"m":return 60*o*1e3;case"h":return 60*o*60*1e3;case"d":return 24*o*60*60*1e3;default:return-1}}generateTokenId(){const e=new Uint8Array(12);crypto.getRandomValues(e);const r=Array.from(e,e=>e.toString(16).padStart(2,"0")).join("");return`appr_${Date.now()}_${r}`}async signToken(e,r,o){const t=JSON.stringify({agentDid:e,scopes:r,expiresAt:o});return btoa(t).substring(0,32)}}
@@ -82,10 +82,10 @@ export declare class MessageStream implements AsyncIterableIterator<AgentMessage
82
82
  * Return method for iterator protocol.
83
83
  * Closes the stream and completes iteration.
84
84
  *
85
- * @param value - Optional value (ignored)
85
+ * @param _value - Optional value (ignored)
86
86
  * @returns Promise resolving to done result
87
87
  */
88
- return(value?: any): Promise<IteratorResult<AgentMessage>>;
88
+ return(_value?: unknown): Promise<IteratorResult<AgentMessage>>;
89
89
  /**
90
90
  * Throw method for iterator protocol.
91
91
  * Closes the stream with error.
@@ -93,7 +93,7 @@ export declare class MessageStream implements AsyncIterableIterator<AgentMessage
93
93
  * @param error - Error to propagate
94
94
  * @returns Promise resolving to done result
95
95
  */
96
- throw(error?: any): Promise<IteratorResult<AgentMessage>>;
96
+ throw(error?: unknown): Promise<IteratorResult<AgentMessage>>;
97
97
  /**
98
98
  * Make this object async iterable.
99
99
  * Enables `for await...of` syntax.
@@ -1,382 +1 @@
1
- /**
2
- * @fileoverview Async iterator API for xBind message streams.
3
- *
4
- * Provides modern async iteration patterns for consuming message streams
5
- * with backpressure handling, stream cancellation, and error propagation.
6
- *
7
- * @example
8
- * ```typescript
9
- * // Subscribe to messages with async iteration
10
- * for await (const message of agent.subscribe({ from: 'did:key:alice' })) {
11
- * console.log('Received:', message.payload);
12
- * }
13
- * ```
14
- *
15
- * @module async-iterators
16
- */
17
- /**
18
- * Async iterable message stream.
19
- *
20
- * Implements AsyncIterableIterator for use with `for await...of` syntax.
21
- * Handles backpressure, cancellation, and error propagation.
22
- */
23
- export class MessageStream {
24
- agent;
25
- options;
26
- state;
27
- constructor(agent, options = {}) {
28
- this.agent = agent;
29
- this.options = {
30
- from: options.from,
31
- scope: options.scope,
32
- bufferSize: options.bufferSize ?? 100,
33
- signal: options.signal,
34
- allowCleartext: options.allowCleartext ?? false,
35
- };
36
- this.state = {
37
- buffer: [],
38
- pending: [],
39
- done: false,
40
- };
41
- // Setup abort signal handler
42
- if (this.options.signal) {
43
- this.options.signal.addEventListener('abort', () => {
44
- this.close(new Error('Stream aborted'));
45
- });
46
- }
47
- // Register envelope handler
48
- const handler = (envelope) => {
49
- void this.handleEnvelope(envelope);
50
- };
51
- // Get first transport adapter and register handler
52
- const transports = this.agent.getTransports();
53
- const transport = transports[0];
54
- if (transport) {
55
- transport.onReceive(handler);
56
- this.state.cleanup = () => {
57
- // Remove handler by creating new transport without this handler
58
- // (Transport interface doesn't support handler removal)
59
- };
60
- }
61
- }
62
- /**
63
- * Handle incoming envelope from transport.
64
- * @internal
65
- */
66
- async handleEnvelope(envelope) {
67
- if (this.state.done)
68
- return;
69
- // Verify and decrypt the envelope
70
- const result = await this.agent.receive(envelope, {
71
- allowCleartext: this.options.allowCleartext,
72
- });
73
- if (!result.ok) {
74
- // Ignore verification errors (not all envelopes are for this stream)
75
- return;
76
- }
77
- const message = result.value;
78
- // Apply filters
79
- if (this.options.from && message.sender !== this.options.from) {
80
- return;
81
- }
82
- if (this.options.scope && message.scope !== this.options.scope) {
83
- return;
84
- }
85
- // Deliver message
86
- if (this.state.pending.length > 0) {
87
- // Consumer is waiting - deliver immediately
88
- const resolve = this.state.pending.shift();
89
- resolve({ value: message, done: false });
90
- }
91
- else if (this.state.buffer.length < this.options.bufferSize) {
92
- // Buffer has space - enqueue
93
- this.state.buffer.push(message);
94
- }
95
- // else: buffer full - drop message (backpressure)
96
- }
97
- /**
98
- * Close the stream with optional error.
99
- * @internal
100
- */
101
- close(error) {
102
- if (this.state.done)
103
- return;
104
- this.state.done = true;
105
- this.state.error = error;
106
- // Resolve all pending next() calls
107
- for (const resolve of this.state.pending) {
108
- if (error) {
109
- resolve({ value: undefined, done: true });
110
- }
111
- else {
112
- resolve({ value: undefined, done: true });
113
- }
114
- }
115
- this.state.pending = [];
116
- // Cleanup resources
117
- if (this.state.cleanup) {
118
- this.state.cleanup();
119
- }
120
- }
121
- /**
122
- * Get next message from the stream.
123
- *
124
- * Returns a promise that resolves when:
125
- * - A message is available in the buffer
126
- * - A new message arrives from the transport
127
- * - The stream is closed
128
- *
129
- * @returns Promise resolving to iterator result
130
- */
131
- async next() {
132
- // Stream already done
133
- if (this.state.done) {
134
- return { value: undefined, done: true };
135
- }
136
- // Check abort signal
137
- if (this.options.signal?.aborted) {
138
- this.close(new Error('Stream aborted'));
139
- return { value: undefined, done: true };
140
- }
141
- // Message available in buffer
142
- if (this.state.buffer.length > 0) {
143
- const message = this.state.buffer.shift();
144
- return { value: message, done: false };
145
- }
146
- // Wait for next message
147
- return new Promise((resolve) => {
148
- this.state.pending.push(resolve);
149
- });
150
- }
151
- /**
152
- * Return method for iterator protocol.
153
- * Closes the stream and completes iteration.
154
- *
155
- * @param value - Optional value (ignored)
156
- * @returns Promise resolving to done result
157
- */
158
- async return(value) {
159
- this.close();
160
- return { value: undefined, done: true };
161
- }
162
- /**
163
- * Throw method for iterator protocol.
164
- * Closes the stream with error.
165
- *
166
- * @param error - Error to propagate
167
- * @returns Promise resolving to done result
168
- */
169
- async throw(error) {
170
- this.close(error instanceof Error ? error : new Error(String(error)));
171
- return { value: undefined, done: true };
172
- }
173
- /**
174
- * Make this object async iterable.
175
- * Enables `for await...of` syntax.
176
- *
177
- * @returns This stream instance
178
- */
179
- [Symbol.asyncIterator]() {
180
- return this;
181
- }
182
- /**
183
- * Get number of buffered messages.
184
- * Useful for monitoring backpressure.
185
- */
186
- get bufferedCount() {
187
- return this.state.buffer.length;
188
- }
189
- /**
190
- * Check if stream is closed.
191
- */
192
- get closed() {
193
- return this.state.done;
194
- }
195
- /**
196
- * Get stream error if any.
197
- */
198
- get error() {
199
- return this.state.error;
200
- }
201
- }
202
- /**
203
- * Collect messages from a stream into an array.
204
- *
205
- * Useful for batch processing or testing. Stream completes when:
206
- * - Limit is reached
207
- * - Timeout expires
208
- * - Stream is aborted via signal
209
- *
210
- * @param agent - Agent instance to collect messages from
211
- * @param options - Collection options
212
- * @returns Promise resolving to array of messages
213
- *
214
- * @example
215
- * ```typescript
216
- * // Collect up to 10 messages with 5 second timeout
217
- * const messages = await collectMessages(agent, {
218
- * from: 'did:key:alice',
219
- * limit: 10,
220
- * timeout: 5000
221
- * });
222
- * ```
223
- */
224
- export async function collectMessages(agent, options = {}) {
225
- const messages = [];
226
- const stream = new MessageStream(agent, options);
227
- // Setup timeout if specified
228
- let timeoutId;
229
- if (options.timeout) {
230
- timeoutId = setTimeout(() => {
231
- void stream.return();
232
- }, options.timeout);
233
- }
234
- try {
235
- for await (const message of stream) {
236
- messages.push(message);
237
- if (options.limit && messages.length >= options.limit) {
238
- break;
239
- }
240
- }
241
- }
242
- finally {
243
- if (timeoutId) {
244
- clearTimeout(timeoutId);
245
- }
246
- if (!stream.closed) {
247
- await stream.return();
248
- }
249
- }
250
- return messages;
251
- }
252
- /**
253
- * Transform message stream with async mapping function.
254
- *
255
- * Enables functional-style stream processing with backpressure preservation.
256
- *
257
- * @param stream - Source message stream
258
- * @param fn - Async transform function
259
- * @returns Async iterable of transformed values
260
- *
261
- * @example
262
- * ```typescript
263
- * const stream = agent.subscribe({ from: 'did:key:alice' });
264
- * const payloads = mapStream(stream, async (msg) => msg.payload);
265
- *
266
- * for await (const payload of payloads) {
267
- * console.log('Payload:', payload);
268
- * }
269
- * ```
270
- */
271
- export async function* mapStream(stream, fn) {
272
- for await (const value of stream) {
273
- yield await fn(value);
274
- }
275
- }
276
- /**
277
- * Filter message stream with async predicate.
278
- *
279
- * Only yields messages that satisfy the predicate.
280
- *
281
- * @param stream - Source message stream
282
- * @param predicate - Async filter predicate
283
- * @returns Async iterable of filtered messages
284
- *
285
- * @example
286
- * ```typescript
287
- * const stream = agent.subscribe({ scope: 'notifications' });
288
- * const urgent = filterStream(stream, async (msg) =>
289
- * msg.payload.priority === 'high'
290
- * );
291
- *
292
- * for await (const message of urgent) {
293
- * await handleUrgent(message);
294
- * }
295
- * ```
296
- */
297
- export async function* filterStream(stream, predicate) {
298
- for await (const value of stream) {
299
- if (await predicate(value)) {
300
- yield value;
301
- }
302
- }
303
- }
304
- /**
305
- * Take first N messages from stream.
306
- *
307
- * Stream completes after yielding N messages.
308
- *
309
- * @param stream - Source message stream
310
- * @param count - Maximum messages to take
311
- * @returns Async iterable with at most count messages
312
- *
313
- * @example
314
- * ```typescript
315
- * const stream = agent.subscribe();
316
- * const first5 = takeStream(stream, 5);
317
- *
318
- * for await (const message of first5) {
319
- * console.log('Message:', message);
320
- * }
321
- * ```
322
- */
323
- export async function* takeStream(stream, count) {
324
- let taken = 0;
325
- for await (const value of stream) {
326
- if (taken >= count)
327
- break;
328
- yield value;
329
- taken++;
330
- }
331
- }
332
- /**
333
- * Merge multiple message streams into one.
334
- *
335
- * Yields messages from all streams as they arrive.
336
- * Completes when all source streams complete.
337
- *
338
- * @param streams - Array of source streams
339
- * @returns Async iterable of merged messages
340
- *
341
- * @example
342
- * ```typescript
343
- * const stream1 = agent.subscribe({ from: 'did:key:alice' });
344
- * const stream2 = agent.subscribe({ from: 'did:key:bob' });
345
- * const merged = mergeStreams([stream1, stream2]);
346
- *
347
- * for await (const message of merged) {
348
- * console.log('From:', message.sender);
349
- * }
350
- * ```
351
- */
352
- export async function* mergeStreams(streams) {
353
- const iterators = streams.map((s) => s[Symbol.asyncIterator]());
354
- const pending = new Map();
355
- // Start all iterators
356
- for (let i = 0; i < iterators.length; i++) {
357
- pending.set(i, iterators[i].next());
358
- }
359
- while (pending.size > 0) {
360
- // Race all pending next() calls
361
- const entries = Array.from(pending.entries());
362
- const winner = await Promise.race(entries.map(async ([idx, promise]) => ({ idx, result: await promise })));
363
- pending.delete(winner.idx);
364
- if (!winner.result.done) {
365
- yield winner.result.value;
366
- // Start next iteration for this stream
367
- pending.set(winner.idx, iterators[winner.idx].next());
368
- }
369
- }
370
- }
371
- /**
372
- * Add subscribe method to Agent prototype.
373
- * @internal
374
- */
375
- export function installAsyncIterators(AgentClass) {
376
- if ('subscribe' in AgentClass.prototype) {
377
- return; // Already installed
378
- }
379
- AgentClass.prototype.subscribe = function (options) {
380
- return new MessageStream(this, options);
381
- };
382
- }
1
+ export class MessageStream{agent;options;state;constructor(t,e={}){this.agent=t,this.options={from:e.from,scope:e.scope,bufferSize:e.bufferSize??100,signal:e.signal,allowCleartext:e.allowCleartext??!1},this.state={buffer:[],pending:[],done:!1},this.options.signal&&this.options.signal.addEventListener("abort",()=>{this.close(new Error("Stream aborted"))});const s=t=>{this.handleEnvelope(t)},n=this.agent.getTransports()[0];n&&(n.onReceive(s),this.state.cleanup=()=>{})}async handleEnvelope(t){if(this.state.done)return;const e=await this.agent.receive(t,{allowCleartext:this.options.allowCleartext});if(!e.ok)return;const s=e.value;if(!(this.options.from&&s.sender!==this.options.from||this.options.scope&&s.scope!==this.options.scope))if(this.state.pending.length>0){this.state.pending.shift()({value:s,done:!1})}else this.state.buffer.length<this.options.bufferSize&&this.state.buffer.push(s)}close(t){if(!this.state.done){this.state.done=!0,this.state.error=t;for(const t of this.state.pending)t({value:void 0,done:!0});this.state.pending=[],this.state.cleanup&&this.state.cleanup()}}async next(){if(this.state.done)return{value:void 0,done:!0};if(this.options.signal?.aborted)return this.close(new Error("Stream aborted")),{value:void 0,done:!0};if(this.state.buffer.length>0){return{value:this.state.buffer.shift(),done:!1}}return new Promise(t=>{this.state.pending.push(t)})}async return(t){return this.close(),{value:void 0,done:!0}}async throw(t){return this.close(t instanceof Error?t:new Error(String(t))),{value:void 0,done:!0}}[Symbol.asyncIterator](){return this}get bufferedCount(){return this.state.buffer.length}get closed(){return this.state.done}get error(){return this.state.error}}export async function collectMessages(t,e={}){const s=[],n=new MessageStream(t,e);let o;e.timeout&&(o=setTimeout(()=>{n.return()},e.timeout));try{for await(const t of n)if(s.push(t),e.limit&&s.length>=e.limit)break}finally{o&&clearTimeout(o),n.closed||await n.return()}return s}export async function*mapStream(t,e){for await(const s of t)yield await e(s)}export async function*filterStream(t,e){for await(const s of t)await e(s)&&(yield s)}export async function*takeStream(t,e){let s=0;for await(const n of t){if(s>=e)break;yield n,s++}}export async function*mergeStreams(t){const e=t.map(t=>t[Symbol.asyncIterator]()),s=new Map;for(let t=0;t<e.length;t++)s.set(t,e[t].next());for(;s.size>0;){const t=Array.from(s.entries()),n=await Promise.race(t.map(async([t,e])=>({idx:t,result:await e})));s.delete(n.idx),n.result.done||(yield n.result.value,s.set(n.idx,e[n.idx].next()))}}export function installAsyncIterators(t){"subscribe"in t.prototype||(t.prototype.subscribe=function(t){return new MessageStream(this,t)})}