@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,102 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.RetryTransportAdapter=void 0;class RetryTransportAdapter{inner;maxRetries;baseDelayMs;maxJitterMs;constructor(e,t={}){this.inner=e,this.maxRetries=t.maxRetries??3,this.baseDelayMs=t.baseDelayMs??1e3,this.maxJitterMs=t.maxJitterMs??200}async send(e,t){let r;for(let s=0;s<=this.maxRetries;s++){const i=await this.inner.send(e,t);if(i.ok)return i;if(r=i.error,s<this.maxRetries){const e=Math.pow(2,s)*this.baseDelayMs,t=new Uint32Array(1);crypto.getRandomValues(t);const r=t[0]/4294967295*this.maxJitterMs*2-this.maxJitterMs;await this.sleep(e+r)}}throw new Error(`Failed after ${this.maxRetries} retries: ${r??"unknown error"}`)}onReceive(e){this.inner.onReceive(e)}dispose(){this.inner.dispose()}sleep(e){return new Promise(t=>setTimeout(t,e))}}exports.RetryTransportAdapter=RetryTransportAdapter;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RetryTransportAdapter = void 0;
4
+ /* ── Implementation ── */
5
+ /**
6
+ * Decorator that adds exponential backoff retry logic to any transport adapter.
7
+ *
8
+ * Retry delays follow exponential backoff with jitter:
9
+ * - Formula: 2^attempt * baseDelay + jitter
10
+ * - Jitter: Math.random() * maxJitter * 2 - maxJitter
11
+ * - Default delays: 1s, 2s, 4s (with ±200ms jitter)
12
+ *
13
+ * Use case: Push notification delivery failures requiring automatic retry.
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const transport = new RetryTransportAdapter(baseTransport, {
18
+ * maxRetries: 3,
19
+ * baseDelayMs: 1000,
20
+ * maxJitterMs: 200
21
+ * });
22
+ * ```
23
+ */
24
+ class RetryTransportAdapter {
25
+ inner;
26
+ maxRetries;
27
+ baseDelayMs;
28
+ maxJitterMs;
29
+ /**
30
+ * Create a new RetryTransportAdapter wrapping an existing transport.
31
+ *
32
+ * @param inner - The transport adapter to wrap with retry logic
33
+ * @param options - Retry configuration options
34
+ */
35
+ constructor(inner, options = {}) {
36
+ this.inner = inner;
37
+ this.maxRetries = options.maxRetries ?? 3;
38
+ this.baseDelayMs = options.baseDelayMs ?? 1000;
39
+ this.maxJitterMs = options.maxJitterMs ?? 200;
40
+ }
41
+ /**
42
+ * Send an envelope with exponential backoff retry logic.
43
+ *
44
+ * Retries on all error types (SEND_FAILED, NETWORK_ERROR, RECIPIENT_UNREACHABLE, TIMEOUT).
45
+ * Throws error after all retries are exhausted.
46
+ *
47
+ * @param envelope - The envelope to send
48
+ * @param recipientDid - The recipient's DID
49
+ * @returns Result with void on success, or TransportError on failure
50
+ * @throws Error if all retry attempts are exhausted
51
+ */
52
+ async send(envelope, recipientDid) {
53
+ let lastError;
54
+ for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
55
+ const result = await this.inner.send(envelope, recipientDid);
56
+ // Success - return immediately
57
+ if (result.ok) {
58
+ return result;
59
+ }
60
+ // Store error for final throw
61
+ lastError = result.error;
62
+ // Don't delay after final attempt
63
+ if (attempt < this.maxRetries) {
64
+ // Exponential backoff: 2^attempt * baseDelay + jitter
65
+ const delay = Math.pow(2, attempt) * this.baseDelayMs;
66
+ // SAFETY: Using crypto.getRandomValues for OWASP-compliant secure random jitter
67
+ const jitterArray = new Uint32Array(1);
68
+ crypto.getRandomValues(jitterArray);
69
+ const jitter = (jitterArray[0] / 0xffffffff) * this.maxJitterMs * 2 -
70
+ this.maxJitterMs;
71
+ await this.sleep(delay + jitter);
72
+ }
73
+ }
74
+ // All retries exhausted - throw error with clear message
75
+ throw new Error(`Failed after ${this.maxRetries} retries: ${lastError ?? 'unknown error'}`);
76
+ }
77
+ /**
78
+ * Register a handler for incoming envelopes.
79
+ * Delegates directly to the inner transport.
80
+ *
81
+ * @param handler - The envelope handler function
82
+ */
83
+ onReceive(handler) {
84
+ this.inner.onReceive(handler);
85
+ }
86
+ /**
87
+ * Shut down the transport.
88
+ * Delegates directly to the inner transport.
89
+ */
90
+ dispose() {
91
+ this.inner.dispose();
92
+ }
93
+ /**
94
+ * Sleep for a specified duration.
95
+ *
96
+ * @param ms - Duration in milliseconds
97
+ */
98
+ sleep(ms) {
99
+ return new Promise((resolve) => setTimeout(resolve, ms));
100
+ }
101
+ }
102
+ exports.RetryTransportAdapter = RetryTransportAdapter;
@@ -1 +1,533 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.DEFAULT_SERVICE_WORKER_CONFIG=exports.MemoryStorageAdapter=exports.IndexedDBAdapter=exports.LocalStorageAdapter=void 0,exports.detectRuntime=detectRuntime,exports.isBrowser=isBrowser,exports.isNode=isNode,exports.isServiceWorker=isServiceWorker,exports.getRandomBytes=getRandomBytes,exports.generateUUID=generateUUID,exports.isWasmSupported=isWasmSupported,exports.loadWasmModule=loadWasmModule,exports.detectCapabilities=detectCapabilities,exports.installNodePolyfills=installNodePolyfills,exports.initServiceWorker=initServiceWorker;const shared_1=require("../../_deps/shared/index.js");function detectRuntime(){return"undefined"!=typeof self&&"ServiceWorkerGlobalScope"in self?"service-worker":"undefined"!=typeof self&&"WorkerGlobalScope"in self&&"importScripts"in self?"web-worker":"undefined"!=typeof window&&"undefined"!=typeof document?"browser":"undefined"!=typeof process&&process.versions&&process.versions.node?"node":"unknown"}function isBrowser(){const e=detectRuntime();return"browser"===e||"service-worker"===e||"web-worker"===e}function isNode(){return"node"===detectRuntime()}function isServiceWorker(){return"service-worker"===detectRuntime()}function getRandomBytes(e){if("undefined"==typeof crypto||!crypto.getRandomValues)throw new Error("Web Crypto API not available - secure random generation impossible");const t=new Uint8Array(e);return crypto.getRandomValues(t),t}function generateUUID(){if("undefined"!=typeof crypto&&crypto.randomUUID)return crypto.randomUUID();const e=getRandomBytes(16),t=e[6],r=e[8];void 0!==t&&(e[6]=15&t|64),void 0!==r&&(e[8]=63&r|128);const o=Array.from(e).map(e=>e.toString(16).padStart(2,"0")).join("");return[o.slice(0,8),o.slice(8,12),o.slice(12,16),o.slice(16,20),o.slice(20,32)].join("-")}class LocalStorageAdapter{prefix;constructor(e="xbind:"){if(this.prefix=e,"undefined"==typeof localStorage)throw new Error("localStorage not available in this environment")}async setItem(e,t){const r=this.prefix+e,o=JSON.stringify(t);localStorage.setItem(r,o)}async getItem(e){const t=this.prefix+e,r=localStorage.getItem(t);if(null===r)return null;try{return JSON.parse(r)}catch{return null}}async removeItem(e){const t=this.prefix+e;localStorage.removeItem(t)}async clear(){Object.keys(localStorage).filter(e=>e.startsWith(this.prefix)).forEach(e=>localStorage.removeItem(e))}}exports.LocalStorageAdapter=LocalStorageAdapter;class IndexedDBAdapter{dbName;storeName;version;db=null;constructor(e="xbind-storage",t="keyval",r=1){this.dbName=e,this.storeName=t,this.version=r}async ensureDB(){return this.db?this.db:new Promise((e,t)=>{const r=indexedDB.open(this.dbName,this.version);r.onerror=()=>t(r.error),r.onsuccess=()=>{this.db=r.result,e(r.result)},r.onupgradeneeded=e=>{const t=e.target.result;t.objectStoreNames.contains(this.storeName)||t.createObjectStore(this.storeName)}})}async setItem(e,t){const r=(await this.ensureDB()).transaction(this.storeName,"readwrite").objectStore(this.storeName);return new Promise((o,s)=>{const n=r.put(t,e);n.onerror=()=>s(n.error),n.onsuccess=()=>o()})}async getItem(e){const t=(await this.ensureDB()).transaction(this.storeName,"readonly").objectStore(this.storeName);return new Promise((r,o)=>{const s=t.get(e);s.onerror=()=>o(s.error),s.onsuccess=()=>{const e=s.result;r(void 0===e?null:e)}})}async removeItem(e){const t=(await this.ensureDB()).transaction(this.storeName,"readwrite").objectStore(this.storeName);return new Promise((r,o)=>{const s=t.delete(e);s.onerror=()=>o(s.error),s.onsuccess=()=>r()})}async clear(){const e=(await this.ensureDB()).transaction(this.storeName,"readwrite").objectStore(this.storeName);return new Promise((t,r)=>{const o=e.clear();o.onerror=()=>r(o.error),o.onsuccess=()=>t()})}close(){this.db&&(this.db.close(),this.db=null)}}exports.IndexedDBAdapter=IndexedDBAdapter;class MemoryStorageAdapter{store=new Map;async setItem(e,t){this.store.set(e,t)}async getItem(e){const t=this.store.get(e);return void 0===t?null:t}async removeItem(e){this.store.delete(e)}async clear(){this.store.clear()}}function isWasmSupported(){try{if("undefined"==typeof WebAssembly)return!1;const e=new WebAssembly.Module(new Uint8Array([0,97,115,109,1,0,0,0]));if(!(e instanceof WebAssembly.Module))return!1;return new WebAssembly.Instance(e)instanceof WebAssembly.Instance}catch{return!1}}async function loadWasmModule(e,t){if(!isWasmSupported())return(0,shared_1.err)("WASM_NOT_SUPPORTED");try{if(void 0!==WebAssembly.instantiateStreaming){const r=await fetch(e),o=await WebAssembly.instantiateStreaming(r,t);return(0,shared_1.ok)(o.instance)}const r=await fetch(e),o=await r.arrayBuffer(),s=await WebAssembly.instantiate(o,t);return(0,shared_1.ok)(s.instance)}catch(e){return console.error("WASM load failed:",e),(0,shared_1.err)("WASM_LOAD_FAILED")}}async function detectCapabilities(){const e={webCrypto:"undefined"!=typeof crypto&&!!crypto.subtle,subtleCrypto:"undefined"!=typeof crypto&&!!crypto.subtle,ed25519:!1,x25519:!1,wasm:isWasmSupported(),indexedDB:"undefined"!=typeof indexedDB,localStorage:"undefined"!=typeof localStorage,serviceWorker:"undefined"!=typeof navigator&&"serviceWorker"in navigator,webWorker:"undefined"!=typeof Worker,fetch:"undefined"!=typeof fetch,textEncoding:"undefined"!=typeof TextEncoder&&"undefined"!=typeof TextDecoder};if(e.subtleCrypto)try{await crypto.subtle.generateKey({name:"Ed25519"},!0,["sign","verify"]),e.ed25519=!0}catch{e.ed25519=!1}if(e.subtleCrypto)try{await crypto.subtle.generateKey({name:"X25519"},!0,["deriveBits"]),e.x25519=!0}catch{e.x25519=!1}return e}function installNodePolyfills(){isBrowser()&&(void 0===globalThis.process&&(globalThis.process={env:{},versions:{},nextTick:e=>Promise.resolve().then(e)}),void 0===globalThis.Buffer&&(globalThis.Buffer={from:(e,t)=>{if(e instanceof Uint8Array)return e;if("base64"===t){const t=atob(e);return new Uint8Array(t.split("").map(e=>e.charCodeAt(0)))}return(new TextEncoder).encode(e)},alloc:e=>new Uint8Array(e)}),void 0===globalThis.global&&(globalThis.global=globalThis))}function initServiceWorker(e={}){const t={...exports.DEFAULT_SERVICE_WORKER_CONFIG,...e};if(!isServiceWorker())throw new Error("initServiceWorker() must be called from service worker context");self.__xbind_sw_config=t,console.log("[xBind] Service worker initialized with config:",t)}exports.MemoryStorageAdapter=MemoryStorageAdapter,exports.DEFAULT_SERVICE_WORKER_CONFIG={wasmCacheStrategy:"cache-first",wasmCacheMaxAge:864e5,enableBackgroundSync:!0};
1
+ "use strict";
2
+ /**
3
+ * Browser Runtime Compatibility Layer
4
+ *
5
+ * Provides polyfills and runtime detection for browser environments.
6
+ * Ensures xBind works seamlessly in Chrome, Firefox, Safari, and service workers.
7
+ *
8
+ * @module runtime/browser
9
+ * @packageDocumentation
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.DEFAULT_SERVICE_WORKER_CONFIG = exports.MemoryStorageAdapter = exports.IndexedDBAdapter = exports.LocalStorageAdapter = void 0;
13
+ exports.detectRuntime = detectRuntime;
14
+ exports.isBrowser = isBrowser;
15
+ exports.isNode = isNode;
16
+ exports.isServiceWorker = isServiceWorker;
17
+ exports.getRandomBytes = getRandomBytes;
18
+ exports.generateUUID = generateUUID;
19
+ exports.isWasmSupported = isWasmSupported;
20
+ exports.loadWasmModule = loadWasmModule;
21
+ exports.detectCapabilities = detectCapabilities;
22
+ exports.installNodePolyfills = installNodePolyfills;
23
+ exports.initServiceWorker = initServiceWorker;
24
+ const shared_1 = require("../../_deps/shared/index.js");
25
+ /**
26
+ * Detect the current runtime environment.
27
+ *
28
+ * @returns The detected runtime environment type
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * import { detectRuntime } from '@private.me/xbind/runtime/browser';
33
+ *
34
+ * const runtime = detectRuntime();
35
+ * console.log('Running in:', runtime);
36
+ * // => 'browser' | 'node' | 'service-worker' | 'web-worker' | 'unknown'
37
+ * ```
38
+ */
39
+ function detectRuntime() {
40
+ // Service Worker context
41
+ if (typeof self !== 'undefined' && 'ServiceWorkerGlobalScope' in self) {
42
+ return 'service-worker';
43
+ }
44
+ // Web Worker context
45
+ if (typeof self !== 'undefined' && 'WorkerGlobalScope' in self && 'importScripts' in self) {
46
+ return 'web-worker';
47
+ }
48
+ // Browser context (window and document available)
49
+ if (typeof window !== 'undefined' && typeof document !== 'undefined') {
50
+ return 'browser';
51
+ }
52
+ // Node.js context (process and global available)
53
+ if (typeof process !== 'undefined' && process.versions && process.versions.node) {
54
+ return 'node';
55
+ }
56
+ return 'unknown';
57
+ }
58
+ /**
59
+ * Check if running in a browser environment.
60
+ *
61
+ * @returns True if running in browser, service worker, or web worker
62
+ */
63
+ function isBrowser() {
64
+ const runtime = detectRuntime();
65
+ return runtime === 'browser' || runtime === 'service-worker' || runtime === 'web-worker';
66
+ }
67
+ /**
68
+ * Check if running in Node.js environment.
69
+ *
70
+ * @returns True if running in Node.js
71
+ */
72
+ function isNode() {
73
+ return detectRuntime() === 'node';
74
+ }
75
+ /**
76
+ * Check if running in a service worker.
77
+ *
78
+ * @returns True if running in service worker context
79
+ */
80
+ function isServiceWorker() {
81
+ return detectRuntime() === 'service-worker';
82
+ }
83
+ /* ── Crypto Compatibility ── */
84
+ /**
85
+ * Browser-compatible random bytes generator.
86
+ * Uses Web Crypto API's getRandomValues.
87
+ *
88
+ * @param length - Number of random bytes to generate
89
+ * @returns Uint8Array of cryptographically secure random bytes
90
+ *
91
+ * @throws {Error} If Web Crypto API is not available
92
+ *
93
+ * @example
94
+ * ```typescript
95
+ * import { getRandomBytes } from '@private.me/xbind/runtime/browser';
96
+ *
97
+ * const nonce = getRandomBytes(16);
98
+ * console.log('Random nonce:', nonce);
99
+ * ```
100
+ */
101
+ function getRandomBytes(length) {
102
+ if (typeof crypto === 'undefined' || !crypto.getRandomValues) {
103
+ throw new Error('Web Crypto API not available - secure random generation impossible');
104
+ }
105
+ const bytes = new Uint8Array(length);
106
+ crypto.getRandomValues(bytes);
107
+ return bytes;
108
+ }
109
+ /**
110
+ * Generate a cryptographically secure random UUID.
111
+ * Uses Web Crypto API's randomUUID if available, falls back to manual generation.
112
+ *
113
+ * @returns UUID v4 string (e.g., "550e8400-e29b-41d4-a716-446655440000")
114
+ *
115
+ * @example
116
+ * ```typescript
117
+ * import { generateUUID } from '@private.me/xbind/runtime/browser';
118
+ *
119
+ * const id = generateUUID();
120
+ * console.log('Generated UUID:', id);
121
+ * ```
122
+ */
123
+ function generateUUID() {
124
+ // Use native randomUUID if available (modern browsers)
125
+ if (typeof crypto !== 'undefined' && crypto.randomUUID) {
126
+ return crypto.randomUUID();
127
+ }
128
+ // Fallback: manual UUID v4 generation
129
+ const bytes = getRandomBytes(16);
130
+ // Set version (4) and variant (RFC 4122)
131
+ const byte6 = bytes[6];
132
+ const byte8 = bytes[8];
133
+ if (byte6 !== undefined)
134
+ bytes[6] = (byte6 & 0x0f) | 0x40; // Version 4
135
+ if (byte8 !== undefined)
136
+ bytes[8] = (byte8 & 0x3f) | 0x80; // Variant 10
137
+ // Format as UUID string
138
+ const hex = Array.from(bytes)
139
+ .map(b => b.toString(16).padStart(2, '0'))
140
+ .join('');
141
+ return [
142
+ hex.slice(0, 8),
143
+ hex.slice(8, 12),
144
+ hex.slice(12, 16),
145
+ hex.slice(16, 20),
146
+ hex.slice(20, 32),
147
+ ].join('-');
148
+ }
149
+ /**
150
+ * LocalStorage-based implementation of BrowserStorage.
151
+ * Suitable for browser environments with persistent storage needs.
152
+ */
153
+ class LocalStorageAdapter {
154
+ prefix;
155
+ /**
156
+ * Create a new LocalStorage adapter.
157
+ *
158
+ * @param prefix - Key prefix to avoid collisions (default: 'xbind:')
159
+ */
160
+ constructor(prefix = 'xbind:') {
161
+ this.prefix = prefix;
162
+ if (typeof localStorage === 'undefined') {
163
+ throw new Error('localStorage not available in this environment');
164
+ }
165
+ }
166
+ async setItem(key, value) {
167
+ const fullKey = this.prefix + key;
168
+ const serialized = JSON.stringify(value);
169
+ localStorage.setItem(fullKey, serialized);
170
+ }
171
+ async getItem(key) {
172
+ const fullKey = this.prefix + key;
173
+ const raw = localStorage.getItem(fullKey);
174
+ if (raw === null) {
175
+ return null;
176
+ }
177
+ try {
178
+ return JSON.parse(raw);
179
+ }
180
+ catch {
181
+ return null;
182
+ }
183
+ }
184
+ async removeItem(key) {
185
+ const fullKey = this.prefix + key;
186
+ localStorage.removeItem(fullKey);
187
+ }
188
+ async clear() {
189
+ const keys = Object.keys(localStorage).filter(k => k.startsWith(this.prefix));
190
+ keys.forEach(k => localStorage.removeItem(k));
191
+ }
192
+ }
193
+ exports.LocalStorageAdapter = LocalStorageAdapter;
194
+ /**
195
+ * IndexedDB-based implementation of BrowserStorage.
196
+ * Suitable for larger datasets and service workers.
197
+ */
198
+ class IndexedDBAdapter {
199
+ dbName;
200
+ storeName;
201
+ version;
202
+ db = null;
203
+ /**
204
+ * Create a new IndexedDB adapter.
205
+ *
206
+ * @param dbName - Database name (default: 'xbind-storage')
207
+ * @param storeName - Object store name (default: 'keyval')
208
+ * @param version - Database version (default: 1)
209
+ */
210
+ constructor(dbName = 'xbind-storage', storeName = 'keyval', version = 1) {
211
+ this.dbName = dbName;
212
+ this.storeName = storeName;
213
+ this.version = version;
214
+ }
215
+ /**
216
+ * Initialize the database connection.
217
+ * Called automatically by storage operations.
218
+ */
219
+ async ensureDB() {
220
+ if (this.db) {
221
+ return this.db;
222
+ }
223
+ return new Promise((resolve, reject) => {
224
+ const request = indexedDB.open(this.dbName, this.version);
225
+ request.onerror = () => reject(request.error);
226
+ request.onsuccess = () => {
227
+ this.db = request.result;
228
+ resolve(request.result);
229
+ };
230
+ request.onupgradeneeded = (event) => {
231
+ const db = event.target.result;
232
+ if (!db.objectStoreNames.contains(this.storeName)) {
233
+ db.createObjectStore(this.storeName);
234
+ }
235
+ };
236
+ });
237
+ }
238
+ async setItem(key, value) {
239
+ const db = await this.ensureDB();
240
+ const tx = db.transaction(this.storeName, 'readwrite');
241
+ const store = tx.objectStore(this.storeName);
242
+ return new Promise((resolve, reject) => {
243
+ const request = store.put(value, key);
244
+ request.onerror = () => reject(request.error);
245
+ request.onsuccess = () => resolve();
246
+ });
247
+ }
248
+ async getItem(key) {
249
+ const db = await this.ensureDB();
250
+ const tx = db.transaction(this.storeName, 'readonly');
251
+ const store = tx.objectStore(this.storeName);
252
+ return new Promise((resolve, reject) => {
253
+ const request = store.get(key);
254
+ request.onerror = () => reject(request.error);
255
+ request.onsuccess = () => {
256
+ const value = request.result;
257
+ resolve(value === undefined ? null : value);
258
+ };
259
+ });
260
+ }
261
+ async removeItem(key) {
262
+ const db = await this.ensureDB();
263
+ const tx = db.transaction(this.storeName, 'readwrite');
264
+ const store = tx.objectStore(this.storeName);
265
+ return new Promise((resolve, reject) => {
266
+ const request = store.delete(key);
267
+ request.onerror = () => reject(request.error);
268
+ request.onsuccess = () => resolve();
269
+ });
270
+ }
271
+ async clear() {
272
+ const db = await this.ensureDB();
273
+ const tx = db.transaction(this.storeName, 'readwrite');
274
+ const store = tx.objectStore(this.storeName);
275
+ return new Promise((resolve, reject) => {
276
+ const request = store.clear();
277
+ request.onerror = () => reject(request.error);
278
+ request.onsuccess = () => resolve();
279
+ });
280
+ }
281
+ /**
282
+ * Close the database connection.
283
+ * Should be called when storage is no longer needed.
284
+ */
285
+ close() {
286
+ if (this.db) {
287
+ this.db.close();
288
+ this.db = null;
289
+ }
290
+ }
291
+ }
292
+ exports.IndexedDBAdapter = IndexedDBAdapter;
293
+ /**
294
+ * In-memory storage implementation for testing and ephemeral use cases.
295
+ */
296
+ class MemoryStorageAdapter {
297
+ store = new Map();
298
+ async setItem(key, value) {
299
+ this.store.set(key, value);
300
+ }
301
+ async getItem(key) {
302
+ const value = this.store.get(key);
303
+ return value === undefined ? null : value;
304
+ }
305
+ async removeItem(key) {
306
+ this.store.delete(key);
307
+ }
308
+ async clear() {
309
+ this.store.clear();
310
+ }
311
+ }
312
+ exports.MemoryStorageAdapter = MemoryStorageAdapter;
313
+ /**
314
+ * Check if WebAssembly is supported in the current environment.
315
+ *
316
+ * @returns True if WebAssembly is supported
317
+ *
318
+ * @example
319
+ * ```typescript
320
+ * import { isWasmSupported } from '@private.me/xbind/runtime/browser';
321
+ *
322
+ * if (isWasmSupported()) {
323
+ * console.log('WASM is supported - using post-quantum crypto');
324
+ * } else {
325
+ * console.log('WASM not supported - falling back to classical crypto');
326
+ * }
327
+ * ```
328
+ */
329
+ function isWasmSupported() {
330
+ try {
331
+ if (typeof WebAssembly === 'undefined') {
332
+ return false;
333
+ }
334
+ // Test instantiation with minimal WASM module
335
+ const module = new WebAssembly.Module(new Uint8Array([0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00]));
336
+ if (!(module instanceof WebAssembly.Module)) {
337
+ return false;
338
+ }
339
+ const instance = new WebAssembly.Instance(module);
340
+ return instance instanceof WebAssembly.Instance;
341
+ }
342
+ catch {
343
+ return false;
344
+ }
345
+ }
346
+ /**
347
+ * Load and instantiate a WebAssembly module from a URL.
348
+ *
349
+ * @param url - URL to WASM module
350
+ * @param importObject - Optional imports for WASM module
351
+ * @returns Result containing the WASM instance or error
352
+ *
353
+ * @example
354
+ * ```typescript
355
+ * import { loadWasmModule } from '@private.me/xbind/runtime/browser';
356
+ *
357
+ * const result = await loadWasmModule('/mldsa.wasm');
358
+ * if (!result.ok) {
359
+ * console.error('Failed to load WASM:', result.error);
360
+ * return;
361
+ * }
362
+ *
363
+ * const instance = result.value;
364
+ * // Use WASM exports...
365
+ * ```
366
+ */
367
+ async function loadWasmModule(url, importObject) {
368
+ if (!isWasmSupported()) {
369
+ return (0, shared_1.err)('WASM_NOT_SUPPORTED');
370
+ }
371
+ try {
372
+ // Use streaming compilation if available (faster)
373
+ if (typeof WebAssembly.instantiateStreaming !== 'undefined') {
374
+ const response = await fetch(url);
375
+ const result = await WebAssembly.instantiateStreaming(response, importObject);
376
+ return (0, shared_1.ok)(result.instance);
377
+ }
378
+ // Fallback: fetch as ArrayBuffer then compile
379
+ const response = await fetch(url);
380
+ const buffer = await response.arrayBuffer();
381
+ const result = await WebAssembly.instantiate(buffer, importObject);
382
+ return (0, shared_1.ok)(result.instance);
383
+ }
384
+ catch (error) {
385
+ console.error('WASM load failed:', error);
386
+ return (0, shared_1.err)('WASM_LOAD_FAILED');
387
+ }
388
+ }
389
+ /**
390
+ * Detect browser capabilities and feature support.
391
+ *
392
+ * @returns Object describing available browser features
393
+ *
394
+ * @example
395
+ * ```typescript
396
+ * import { detectCapabilities } from '@private.me/xbind/runtime/browser';
397
+ *
398
+ * const caps = await detectCapabilities();
399
+ *
400
+ * if (!caps.webCrypto) {
401
+ * throw new Error('WebCrypto required for xBind');
402
+ * }
403
+ *
404
+ * if (!caps.ed25519) {
405
+ * console.warn('Ed25519 not supported - using polyfill');
406
+ * }
407
+ *
408
+ * if (caps.serviceWorker) {
409
+ * console.log('Service workers supported - can run in background');
410
+ * }
411
+ * ```
412
+ */
413
+ async function detectCapabilities() {
414
+ // Basic feature detection
415
+ const capabilities = {
416
+ webCrypto: typeof crypto !== 'undefined' && !!crypto.subtle,
417
+ subtleCrypto: typeof crypto !== 'undefined' && !!crypto.subtle,
418
+ ed25519: false,
419
+ x25519: false,
420
+ wasm: isWasmSupported(),
421
+ indexedDB: typeof indexedDB !== 'undefined',
422
+ localStorage: typeof localStorage !== 'undefined',
423
+ serviceWorker: typeof navigator !== 'undefined' && 'serviceWorker' in navigator,
424
+ webWorker: typeof Worker !== 'undefined',
425
+ fetch: typeof fetch !== 'undefined',
426
+ textEncoding: typeof TextEncoder !== 'undefined' && typeof TextDecoder !== 'undefined',
427
+ };
428
+ // Test Ed25519 support (async)
429
+ if (capabilities.subtleCrypto) {
430
+ try {
431
+ await crypto.subtle.generateKey({ name: 'Ed25519' }, true, ['sign', 'verify']);
432
+ capabilities.ed25519 = true;
433
+ }
434
+ catch {
435
+ capabilities.ed25519 = false;
436
+ }
437
+ }
438
+ // Test X25519 support (async)
439
+ if (capabilities.subtleCrypto) {
440
+ try {
441
+ await crypto.subtle.generateKey({ name: 'X25519' }, true, ['deriveBits']);
442
+ capabilities.x25519 = true;
443
+ }
444
+ catch {
445
+ capabilities.x25519 = false;
446
+ }
447
+ }
448
+ return capabilities;
449
+ }
450
+ /* ── Polyfills ── */
451
+ /**
452
+ * Install Node.js compatibility shims for browser environments.
453
+ * Only installs missing APIs - does not override existing implementations.
454
+ *
455
+ * @example
456
+ * ```typescript
457
+ * import { installNodePolyfills } from '@private.me/xbind/runtime/browser';
458
+ *
459
+ * // Install polyfills at application startup
460
+ * installNodePolyfills();
461
+ *
462
+ * // Now Node.js-style code works in browser
463
+ * import { randomBytes } from 'crypto'; // Works!
464
+ * ```
465
+ */
466
+ function installNodePolyfills() {
467
+ // Only install in browser environments
468
+ if (!isBrowser()) {
469
+ return;
470
+ }
471
+ // Polyfill process.env
472
+ if (typeof globalThis.process === 'undefined') {
473
+ globalThis.process = {
474
+ env: {},
475
+ versions: {},
476
+ nextTick: (fn) => Promise.resolve().then(fn),
477
+ };
478
+ }
479
+ // Polyfill Buffer (minimal implementation)
480
+ if (typeof globalThis.Buffer === 'undefined') {
481
+ globalThis.Buffer = {
482
+ from: (data, encoding) => {
483
+ if (data instanceof Uint8Array)
484
+ return data;
485
+ if (encoding === 'base64') {
486
+ const binary = atob(data);
487
+ return new Uint8Array(binary.split('').map(c => c.charCodeAt(0)));
488
+ }
489
+ return new TextEncoder().encode(data);
490
+ },
491
+ alloc: (size) => new Uint8Array(size),
492
+ };
493
+ }
494
+ // Polyfill global
495
+ if (typeof globalThis.global === 'undefined') {
496
+ globalThis.global = globalThis;
497
+ }
498
+ }
499
+ /**
500
+ * Default service worker configuration.
501
+ */
502
+ exports.DEFAULT_SERVICE_WORKER_CONFIG = {
503
+ wasmCacheStrategy: 'cache-first',
504
+ wasmCacheMaxAge: 24 * 60 * 60 * 1000, // 24 hours
505
+ enableBackgroundSync: true,
506
+ };
507
+ /**
508
+ * Initialize xBind for service worker environment.
509
+ * Sets up caching strategies and background sync handlers.
510
+ *
511
+ * @param config - Service worker configuration
512
+ *
513
+ * @example
514
+ * ```typescript
515
+ * // In your service worker (sw.js):
516
+ * import { initServiceWorker } from '@private.me/xbind/runtime/browser';
517
+ *
518
+ * initServiceWorker({
519
+ * wasmCacheStrategy: 'cache-first',
520
+ * wasmCacheMaxAge: 24 * 60 * 60 * 1000,
521
+ * enableBackgroundSync: true,
522
+ * });
523
+ * ```
524
+ */
525
+ function initServiceWorker(config = {}) {
526
+ const fullConfig = { ...exports.DEFAULT_SERVICE_WORKER_CONFIG, ...config };
527
+ if (!isServiceWorker()) {
528
+ throw new Error('initServiceWorker() must be called from service worker context');
529
+ }
530
+ // Store config for use by other service worker handlers
531
+ self.__xbind_sw_config = fullConfig;
532
+ console.log('[xBind] Service worker initialized with config:', fullConfig);
533
+ }